From d09d062f3c6a1d193439b6ddbd18580fcd215570 Mon Sep 17 00:00:00 2001 From: iremyux Date: Tue, 11 Aug 2026 21:12:49 +0200 Subject: [PATCH 1/4] Reject spaces --- .../src/System/Net/Managed/HttpListenerRequest.Managed.cs | 6 +++--- .../tests/InvalidClientRequestTests.cs | 7 +++++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerRequest.Managed.cs b/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerRequest.Managed.cs index 098782eec22151..c40ce3437a925d 100644 --- a/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerRequest.Managed.cs +++ b/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerRequest.Managed.cs @@ -208,15 +208,15 @@ internal void FinishInitialization() internal void AddHeader(string header) { int colon = header.IndexOf(':'); - if (colon == -1 || colon == 0) + if (colon <= 0 || header.AsSpan(0, colon).ContainsAny(' ', '\t')) { _context.ErrorMessage = HttpStatusDescription.Get(400); _context.ErrorStatus = 400; return; } - string name = header.AsSpan(0, colon).Trim().ToString(); - string val = header.AsSpan(colon + 1).Trim().ToString(); + string name = header.AsSpan(0, colon).ToString(); + string val = header.AsSpan(colon + 1).Trim(" \t").ToString(); if (name.Equals("content-length", StringComparison.OrdinalIgnoreCase)) { // To match Windows behavior: diff --git a/src/libraries/System.Net.HttpListener/tests/InvalidClientRequestTests.cs b/src/libraries/System.Net.HttpListener/tests/InvalidClientRequestTests.cs index 67e7c187225fba..aa7a5d81871de5 100644 --- a/src/libraries/System.Net.HttpListener/tests/InvalidClientRequestTests.cs +++ b/src/libraries/System.Net.HttpListener/tests/InvalidClientRequestTests.cs @@ -82,6 +82,13 @@ public static IEnumerable InvalidRequest_TestData() yield return new object[] { "GET {path} HTTP/1.1", null, new string[] { "NoValue" }, null, "Bad Request" }; yield return new object[] { "GET {path} HTTP/1.1", null, new string[] { ":" }, null, "Bad Request" }; + if (Helpers.IsManagedImplementation) + { + yield return new object[] { "GET {path} HTTP/1.1", null, new string[] { " Header: value" }, null, "Bad Request" }; + yield return new object[] { "GET {path} HTTP/1.1", null, new string[] { "\tHeader: value" }, null, "Bad Request" }; + yield return new object[] { "GET {path} HTTP/1.1", null, new string[] { "Header : value" }, null, "Bad Request" }; + yield return new object[] { "GET {path} HTTP/1.1", null, new string[] { "Header\t: value" }, null, "Bad Request" }; + } yield return new object[] { "GET {path} HTTP/1.1", null, new string[] { "\0:value" }, null, "Bad Request" }; yield return new object[] { "GET {path} HTTP/1.1", null, new string[] { "value:\0" }, null, "Bad Request" }; From fa6df8d83b6a8eae3f7aa48947a184690b83331c Mon Sep 17 00:00:00 2001 From: iremyux Date: Tue, 11 Aug 2026 21:39:46 +0200 Subject: [PATCH 2/4] Change order of test data --- .../tests/InvalidClientRequestTests.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/System.Net.HttpListener/tests/InvalidClientRequestTests.cs b/src/libraries/System.Net.HttpListener/tests/InvalidClientRequestTests.cs index aa7a5d81871de5..00c52e667a1fb9 100644 --- a/src/libraries/System.Net.HttpListener/tests/InvalidClientRequestTests.cs +++ b/src/libraries/System.Net.HttpListener/tests/InvalidClientRequestTests.cs @@ -82,6 +82,8 @@ public static IEnumerable InvalidRequest_TestData() yield return new object[] { "GET {path} HTTP/1.1", null, new string[] { "NoValue" }, null, "Bad Request" }; yield return new object[] { "GET {path} HTTP/1.1", null, new string[] { ":" }, null, "Bad Request" }; + yield return new object[] { "GET {path} HTTP/1.1", null, new string[] { "\0:value" }, null, "Bad Request" }; + yield return new object[] { "GET {path} HTTP/1.1", null, new string[] { "value:\0" }, null, "Bad Request" }; if (Helpers.IsManagedImplementation) { yield return new object[] { "GET {path} HTTP/1.1", null, new string[] { " Header: value" }, null, "Bad Request" }; @@ -89,8 +91,6 @@ public static IEnumerable InvalidRequest_TestData() yield return new object[] { "GET {path} HTTP/1.1", null, new string[] { "Header : value" }, null, "Bad Request" }; yield return new object[] { "GET {path} HTTP/1.1", null, new string[] { "Header\t: value" }, null, "Bad Request" }; } - yield return new object[] { "GET {path} HTTP/1.1", null, new string[] { "\0:value" }, null, "Bad Request" }; - yield return new object[] { "GET {path} HTTP/1.1", null, new string[] { "value:\0" }, null, "Bad Request" }; yield return new object[] { "GET {path} HTTP/1.1", "", null, null, "Bad Request" }; yield return new object[] { "GET {path} HTTP/1.1", "Host: \r\n", null, null, "Bad Request" }; From 56c63d0a9a9d6285d45014d36e78122079130670 Mon Sep 17 00:00:00 2001 From: iremyux Date: Wed, 12 Aug 2026 11:23:52 +0200 Subject: [PATCH 3/4] Check if filed name is a token --- .../src/System/Net/Managed/HttpListenerRequest.Managed.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerRequest.Managed.cs b/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerRequest.Managed.cs index c40ce3437a925d..568bcf88e85851 100644 --- a/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerRequest.Managed.cs +++ b/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerRequest.Managed.cs @@ -208,7 +208,7 @@ internal void FinishInitialization() internal void AddHeader(string header) { int colon = header.IndexOf(':'); - if (colon <= 0 || header.AsSpan(0, colon).ContainsAny(' ', '\t')) + if (colon <= 0 || header.AsSpan(0, colon).ContainsAnyExcept(s_validMethodChars)) { _context.ErrorMessage = HttpStatusDescription.Get(400); _context.ErrorStatus = 400; From 4555516fadae569b0af67af88579a2d6e7017935 Mon Sep 17 00:00:00 2001 From: iremyux Date: Wed, 12 Aug 2026 15:12:11 +0200 Subject: [PATCH 4/4] Remove ContainsAnyExcept check --- .../src/System/Net/Managed/HttpListenerRequest.Managed.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerRequest.Managed.cs b/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerRequest.Managed.cs index 568bcf88e85851..840b0d8fc6205e 100644 --- a/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerRequest.Managed.cs +++ b/src/libraries/System.Net.HttpListener/src/System/Net/Managed/HttpListenerRequest.Managed.cs @@ -208,7 +208,7 @@ internal void FinishInitialization() internal void AddHeader(string header) { int colon = header.IndexOf(':'); - if (colon <= 0 || header.AsSpan(0, colon).ContainsAnyExcept(s_validMethodChars)) + if (colon <= 0) { _context.ErrorMessage = HttpStatusDescription.Get(400); _context.ErrorStatus = 400;