Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.

Commit 06433cd

Browse files
author
Cesar Blum Silveira
committed
Ignore everything but path and query in requests for absolute URIs (#666).
1 parent 4b21411 commit 06433cd

File tree

3 files changed

+106
-3
lines changed

3 files changed

+106
-3
lines changed

src/Microsoft.AspNetCore.Server.Kestrel/Http/Frame.cs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -804,8 +804,21 @@ protected bool TakeStartLine(SocketInput input)
804804
QueryString = queryString;
805805
HttpVersion = httpVersion;
806806

807-
bool caseMatches;
807+
if (requestUrlPath.Length > 0 && requestUrlPath[0] != '/')
808+
{
809+
Uri uri;
810+
if (Uri.TryCreate(requestUrlPath, UriKind.Absolute, out uri))
811+
{
812+
requestUrlPath = uri.PathAndQuery;
813+
}
814+
else
815+
{
816+
ReportCorruptedHttpRequest(new BadHttpRequestException($"Invalid request path: {requestUrlPath}"));
817+
return true;
818+
}
819+
}
808820

821+
bool caseMatches;
809822
if (!string.IsNullOrEmpty(_pathBase) &&
810823
(requestUrlPath.Length == _pathBase.Length || (requestUrlPath.Length > _pathBase.Length && requestUrlPath[_pathBase.Length] == '/')) &&
811824
RequestUrlStartsWithPathBase(requestUrlPath, out caseMatches))

src/Microsoft.AspNetCore.Server.Kestrel/Http/FrameOfT.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ public override async Task RequestProcessingAsync()
5454

5555
InitializeHeaders();
5656

57+
if (_corruptedRequest)
58+
{
59+
await ProduceEnd();
60+
return;
61+
}
62+
5763
while (!_requestProcessingStopping && !TakeMessageHeaders(SocketInput, FrameRequestHeaders))
5864
{
5965
if (SocketInput.RemoteIntakeFin)

test/Microsoft.AspNetCore.Server.Kestrel.FunctionalTests/RequestTests.cs

Lines changed: 86 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ public async Task DoesNotHangOnConnectionCloseRequest()
145145
{
146146
app.Run(async context =>
147147
{
148-
var connection = context.Connection;
149148
await context.Response.WriteAsync("hello, world");
150149
});
151150
});
@@ -174,7 +173,6 @@ public void RequestPathIsNormalized()
174173
{
175174
app.Run(async context =>
176175
{
177-
var connection = context.Connection;
178176
Assert.Equal("/\u00C5", context.Request.PathBase.Value);
179177
Assert.Equal("/B/\u00C5", context.Request.Path.Value);
180178
await context.Response.WriteAsync("hello, world");
@@ -208,6 +206,92 @@ public void RequestPathIsNormalized()
208206
}
209207
}
210208

209+
[Fact]
210+
public void RequestWithFullUriHasSchemeHostAndPortIgnored()
211+
{
212+
var port = PortManager.GetPort();
213+
var builder = new WebHostBuilder()
214+
.UseServer("Microsoft.AspNetCore.Server.Kestrel")
215+
.UseUrls($"http://localhost:{port}")
216+
.Configure(app =>
217+
{
218+
app.Run(async context =>
219+
{
220+
Assert.Equal("/test", context.Request.Path.Value);
221+
Assert.Equal("?arg=value", context.Request.QueryString.Value);
222+
await context.Response.WriteAsync("hello, world");
223+
});
224+
});
225+
226+
using (var host = builder.Build())
227+
{
228+
host.Start();
229+
230+
using (var socket = TestConnection.CreateConnectedLoopbackSocket(port))
231+
{
232+
socket.Send(Encoding.ASCII.GetBytes($"GET http://doesnotmatter:8080/test?arg=value HTTP/1.1\r\n\r\n"));
233+
socket.Shutdown(SocketShutdown.Send);
234+
235+
var response = new StringBuilder();
236+
var buffer = new byte[4096];
237+
while (true)
238+
{
239+
var length = socket.Receive(buffer);
240+
if (length == 0)
241+
{
242+
break;
243+
}
244+
245+
response.Append(Encoding.ASCII.GetString(buffer, 0, length));
246+
}
247+
248+
Assert.StartsWith("HTTP/1.1 200 OK", response.ToString());
249+
}
250+
}
251+
}
252+
253+
[Fact]
254+
public void RequestWithInvalidPathReturns400()
255+
{
256+
var port = PortManager.GetPort();
257+
var builder = new WebHostBuilder()
258+
.UseServer("Microsoft.AspNetCore.Server.Kestrel")
259+
.UseUrls($"http://localhost:{port}")
260+
.Configure(app =>
261+
{
262+
app.Run(async context =>
263+
{
264+
await context.Response.WriteAsync("hello, world");
265+
});
266+
});
267+
268+
using (var host = builder.Build())
269+
{
270+
host.Start();
271+
272+
using (var socket = TestConnection.CreateConnectedLoopbackSocket(port))
273+
{
274+
socket.Send(Encoding.ASCII.GetBytes($"GET invalid HTTP/1.1\r\n\r\n"));
275+
socket.Shutdown(SocketShutdown.Send);
276+
277+
var response = new StringBuilder();
278+
var buffer = new byte[4096];
279+
while (true)
280+
{
281+
var length = socket.Receive(buffer);
282+
if (length == 0)
283+
{
284+
break;
285+
}
286+
287+
response.Append(Encoding.ASCII.GetString(buffer, 0, length));
288+
}
289+
290+
Assert.StartsWith("HTTP/1.1 400 Bad Request", response.ToString());
291+
}
292+
}
293+
}
294+
211295
private async Task TestRemoteIPAddress(string registerAddress, string requestAddress, string expectAddress)
212296
{
213297
var port = PortManager.GetPort();

0 commit comments

Comments
 (0)