Open Szer opened 3 years ago
Can you share Kestrel connection logs? https://docs.microsoft.com/aspnet/core/fundamentals/servers/kestrel?view=aspnetcore-5.0#connection-logging
@shirhatti sure
For request with 0x01 in ASCII (unprintable symbol)
(SOH here is unprintable symbol)
GET / HTTP/1.1
Host: localhost
User-Agent: test r
Accept: */*
T(SOH)est: 123
dbug: Microsoft.AspNetCore.Hosting.Diagnostics[3]
Hosting starting
dbug: Microsoft.AspNetCore.Hosting.Diagnostics[4]
Hosting started
dbug: Microsoft.AspNetCore.Hosting.Diagnostics[0]
Loaded hosting startup assembly ConsoleApp1
dbug: Microsoft.AspNetCore.Server.Kestrel[39]
Connection id "0HM507K3JHR0O" accepted.
dbug: Microsoft.AspNetCore.Server.Kestrel[1]
Connection id "0HM507K3JHR0O" started.
dbug: Microsoft.AspNetCore.Server.Kestrel.Core.Internal.LoggingConnectionMiddleware[0]
ReadAsync[81]
47 45 54 20 2F 20 48 54 54 50 2F 31 2E 31 0D 0A GET / HT TP/1.1..
48 6F 73 74 3A 20 6C 6F 63 61 6C 68 6F 73 74 20 Host: lo calhost
0D 0A 55 73 65 72 2D 41 67 65 6E 74 3A 20 74 65 ..User-A gent: te
73 74 20 72 0D 0A 41 63 63 65 70 74 3A 20 2A 2F st r..Ac cept: */
2A 0D 0A 54 01 65 73 74 3A 20 31 32 33 0D 0A 0D *..T.est : 123...
0A .
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
Request starting HTTP/1.1 GET http://localhost/ - -
dbug: Microsoft.AspNetCore.Server.Kestrel.Core.Internal.LoggingConnectionMiddleware[0]
WriteAsync[160]
48 54 54 50 2F 31 2E 31 20 32 30 30 20 4F 4B 0D HTTP/1.1 200 OK.
0A 44 61 74 65 3A 20 4D 6F 6E 2C 20 31 34 20 44 .Date: M on, 14 D
65 63 20 32 30 32 30 20 31 34 3A 33 32 3A 30 34 ec 2020 14:32:04
20 47 4D 54 0D 0A 43 6F 6E 74 65 6E 74 2D 54 79 GMT..Co ntent-Ty
70 65 3A 20 74 65 78 74 2F 70 6C 61 69 6E 0D 0A pe: text /plain..
53 65 72 76 65 72 3A 20 4B 65 73 74 72 65 6C 0D Server: Kestrel.
0A 43 6F 6E 74 65 6E 74 2D 4C 65 6E 67 74 68 3A .Content -Length:
20 34 31 0D 0A 0D 0A 5B 22 41 63 63 65 70 74 22 41....[ "Accept"
3B 20 22 48 6F 73 74 22 3B 20 22 55 73 65 72 2D ; "Host" ; "User-
41 67 65 6E 74 22 3B 20 22 54 01 65 73 74 22 5D Agent"; "T.est"]
dbug: Microsoft.AspNetCore.Server.Kestrel[9]
Connection id "0HM507K3JHR0O" completed keep alive response.
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
Request finished HTTP/1.1 GET http://localhost/ - - - 200 41 text/plain 47.5235ms
Process finished with exit code 0.
To summarize the data from your gist, the following octets in a header name cause it to be rejected: 0x00 (null), 0x09 (tab), 0x0A (line feed), 0x0D (carriage return), 0x20 (space).
This behavior is currently by design (though we can debate the merits of that design). The parser focuses on the values that are required to parse the structure of the message correctly and is fairly permissive about anything else.
Here's the check for space and tab: https://github.com/dotnet/aspnetcore/blob/4a7ed303fff26e4070e02e385fb22df484f6b81f/src/Servers/Kestrel/Core/src/Internal/Http/HttpParser.cs#L339-L363
The new line characters mess up the line parsing and everything gets rejected as malformed. https://github.com/dotnet/aspnetcore/blob/4a7ed303fff26e4070e02e385fb22df484f6b81f/src/Servers/Kestrel/Core/src/Internal/Http/HttpParser.cs#L216-L220
I don't see the check for the null character.
We've moved this issue to the Backlog milestone. This means that it is not going to be worked on for the coming release. We will reassess the backlog following the current release and consider this item at that time. To learn more about our issue management process and to have better expectation regarding different types of issues you can read our Triage Process.
Thanks for the awesome gist to repro the issue and the connection log! That really helped make it easier to understand what's going on.
We do reject non-ASCII characters in header names. We have a test that verifies we at least reject '\x80' here in our BadHttpRequestTests. kestrel_check.fs incorrectly makes it appear that Kestrel is accepting header names containing non-ASCII bytes (0x80-0xFF) because ASCIIEncoding.GetBytes encodes any Unicode character greater than U+007F as the ASCII question mark ('?'). This can be seen in the connection logs:
dbug: Microsoft.AspNetCore.Server.Kestrel.Core.Internal.LoggingConnectionMiddleware[0]
ReadAsync[78]
47 45 54 20 2F 20 48 54 54 50 2F 31 2E 31 0D 0A GET / HT TP/1.1..
48 6F 73 74 3A 20 6C 6F 63 61 6C 68 6F 73 74 20 Host: lo calhost
0D 0A 55 73 65 72 2D 41 67 65 6E 74 3A 20 74 65 ..User-A gent: te
73 74 20 0D 0A 41 63 63 65 70 74 3A 20 2A 2F 2A st ..Acc ept: */*
0D 0A 54 3F 65 73 74 3A 20 31 32 33 0D 0A ..T?est: 123..
Changing Encoding.ASCII.GetBytes
to Encoding.GetEncoding("ISO-8859-1").GetBytes
in the msg
function should fix this.
The actual code that does the validation is here in StringUtilities which is called by HttpUtilites.GetHeaderName(). As you can see, this code is heavily optimized. It might be difficult to maintain perf while rejecting every character not allowed by the HTTP spec.
I don't see the check for the null character.
That's done as part of StringUtilities.TryGetAsciiString(). The various CheckBytesInAsciiRange overloads reject null characters.
Describe the bug
According to HTTP spec header grammar consists of:
If I will send raw TCP request with invalid char in header name Kestrel will respond with 200 Kestrel shouldn't even start invoking any middleware if request header is invalid, but as you see from repro below it does.
To Reproduce
https://gist.github.com/Szer/d834674e0621d2100a61cd76dcadbcf4
Further technical details
5.0.0
dotnet --info
Runtime Environment: OS Name: Windows OS Version: 10.0.19042 OS Platform: Windows RID: win10-x64 Base Path: C:\Program Files\dotnet\sdk\5.0.101\
Host (useful for support): Version: 5.0.1 Commit: b02e13abab
.NET SDKs installed: 3.1.403 [C:\Program Files\dotnet\sdk] 3.1.404 [C:\Program Files\dotnet\sdk] 5.0.101 [C:\Program Files\dotnet\sdk]
.NET runtimes installed: Microsoft.AspNetCore.All 2.1.23 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.All] Microsoft.AspNetCore.App 2.1.23 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 3.1.10 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.AspNetCore.App 5.0.1 [C:\Program Files\dotnet\shared\Microsoft.AspNetCore.App] Microsoft.NETCore.App 2.1.23 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 3.1.10 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.NETCore.App 5.0.1 [C:\Program Files\dotnet\shared\Microsoft.NETCore.App] Microsoft.WindowsDesktop.App 3.1.10 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App] Microsoft.WindowsDesktop.App 5.0.1 [C:\Program Files\dotnet\shared\Microsoft.WindowsDesktop.App]