Просмотр исходного кода

Throw BadHttpRequestException for non-ASCII in absolute-form targets. (#41334)

Aditya Mandaleeka 3 лет назад
Родитель
Сommit
f6cddc1136

+ 14 - 3
src/Servers/Kestrel/Core/src/Internal/Http/Http1Connection.cs

@@ -512,9 +512,20 @@ internal partial class Http1Connection : HttpProtocol, IRequestProcessor, IHttpO
             previousValue == null || previousValue.Length != target.Length ||
             !StringUtilities.BytesOrdinalEqualsStringAndAscii(previousValue, target))
         {
-            // The previous string does not match what the bytes would convert to,
-            // so we will need to generate a new string.
-            RawTarget = _parsedRawTarget = target.GetAsciiStringNonNullCharacters();
+            try
+            {
+                // The previous string does not match what the bytes would convert to,
+                // so we will need to generate a new string.
+                RawTarget = _parsedRawTarget = target.GetAsciiStringNonNullCharacters();
+            }
+            catch (InvalidOperationException)
+            {
+                // GetAsciiStringNonNullCharacters throws an InvalidOperationException if there are
+                // invalid characters in the string. This is hard to understand/diagnose, so let's
+                // catch it and instead throw a more meaningful error. This matches the behavior in
+                // the origin-form case.
+                ThrowRequestTargetRejected(target);
+            }
 
             // Validation of absolute URIs is slow, but clients
             // should not be sending this form anyways, so perf optimization

+ 9 - 0
src/Servers/Kestrel/test/InMemory.FunctionalTests/BadHttpRequestTests.cs

@@ -212,6 +212,15 @@ public class BadHttpRequestTests : LoggedTest
         }
     }
 
+    [Fact]
+    public Task BadRequestForAbsoluteFormTargetWithNonAsciiChars()
+    {
+        return TestBadRequest(
+            $"GET http://localhost/ÿÿÿ HTTP/1.1\r\n",
+            "400 Bad Request",
+            CoreStrings.FormatBadRequest_InvalidRequestTarget_Detail("http://localhost/\\xFF\\xFF\\xFF"));
+    }
+
     private class BadRequestEventListener : IObserver<KeyValuePair<string, object>>, IDisposable
     {
         private IDisposable _subscription;