Reject requests that have null characters in path

This commit is contained in:
moozzyk 2016-06-01 14:19:17 -07:00
parent 2bbaa52b08
commit 69bd0dc4be
4 changed files with 64 additions and 1 deletions

View File

@ -64,6 +64,12 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Http
// preserves the original head. if the percent-encodings cannot be interpreted as sequence of UTF-8 octets,
// bytes from this till the last scanned one will be copied to the memory pointed by writer.
var byte1 = UnescapePercentEncoding(ref reader, end);
if (byte1 == 0)
{
throw new BadHttpRequestException("The path contains null characters.");
}
if (byte1 == -1)
{
return false;

View File

@ -138,7 +138,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.FunctionalTests
{
app.Run(async context =>
{
var connection = context.Connection;
await context.Response.WriteAsync("hello, world");
});
});

View File

@ -189,6 +189,36 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
}
}
[Theory]
[InlineData("\0")]
[InlineData("%00")]
[InlineData("/\0")]
[InlineData("/%00")]
[InlineData("/\0\0")]
[InlineData("/%00%00")]
[InlineData("/%C8\0")]
[InlineData("/%E8%00%84")]
[InlineData("/%E8%85%00")]
[InlineData("/%F3%00%82%86")]
[InlineData("/%F3%85%00%82")]
[InlineData("/%F3%85%82%00")]
[InlineData("/%E8%85%00")]
[InlineData("/%E8%01%00")]
public async Task BadRequestIfPathContainsNullCharacters(string path)
{
using (var server = new TestServer(context => { return Task.FromResult(0); }))
{
using (var connection = server.CreateConnection())
{
await connection.SendEnd(
$"GET {path} HTTP/1.1",
"",
"");
await ReceiveBadRequestResponse(connection);
}
}
}
private async Task ReceiveBadRequestResponse(TestConnection connection)
{
await connection.Receive(

View File

@ -1170,5 +1170,33 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
}
}
}
[Theory]
[InlineData("/%%2000", "/% 00")]
[InlineData("/%25%30%30", "/%00")]
public async Task PathEscapeTests(string inputPath, string expectedPath)
{
using (var server = new TestServer(async httpContext =>
{
var path = httpContext.Request.Path.Value;
httpContext.Response.Headers["Content-Length"] = new[] {path.Length.ToString() };
await httpContext.Response.WriteAsync(path);
}))
{
using (var connection = server.CreateConnection())
{
await connection.SendEnd(
$"GET {inputPath} HTTP/1.1",
"",
"");
await connection.ReceiveEnd(
"HTTP/1.1 200 OK",
$"Date: {connection.Server.Context.DateHeaderValue}",
$"Content-Length: {expectedPath.Length.ToString()}",
"",
$"{expectedPath}");
}
}
}
}
}