File tree Expand file tree Collapse file tree 3 files changed +56
-1
lines changed
test/InMemory.FunctionalTests Expand file tree Collapse file tree 3 files changed +56
-1
lines changed Original file line number Diff line number Diff line change @@ -626,7 +626,22 @@ private void ValidateNonOriginHostHeader(string hostText)
626
626
if ( ! _absoluteRequestTarget . IsDefaultPort
627
627
|| hostText != _absoluteRequestTarget . Authority + ":" + _absoluteRequestTarget . Port . ToString ( CultureInfo . InvariantCulture ) )
628
628
{
629
- KestrelBadHttpRequestException . Throw ( RequestRejectionReason . InvalidHostHeader , hostText ) ;
629
+ // Superseded by RFC 7230, but notable for back-compat.
630
+ // https://datatracker.ietf.org/doc/html/rfc2616/#section-5.2
631
+ // 1. If Request-URI is an absoluteURI, the host is part of the
632
+ // Request-URI. Any Host header field value in the request MUST be
633
+ // ignored.
634
+ // We don't want to leave the invalid value for the app to accidentally consume,
635
+ // replace it with the value from the request line.
636
+ if ( _context . ServiceContext . ServerOptions . EnableInsecureAbsoluteFormHostOverride )
637
+ {
638
+ hostText = _absoluteRequestTarget . Authority + ":" + _absoluteRequestTarget . Port . ToString ( CultureInfo . InvariantCulture ) ;
639
+ HttpRequestHeaders . HeaderHost = hostText ;
640
+ }
641
+ else
642
+ {
643
+ KestrelBadHttpRequestException . Throw ( RequestRejectionReason . InvalidHostHeader , hostText ) ;
644
+ }
630
645
}
631
646
}
632
647
}
Original file line number Diff line number Diff line change @@ -35,6 +35,21 @@ public class KestrelServerOptions
35
35
36
36
private Func < string , Encoding ? > _responseHeaderEncodingSelector = DefaultHeaderEncodingSelector ;
37
37
38
+ private bool ? _enableInsecureAbsoluteFormHostOverride ;
39
+ internal bool EnableInsecureAbsoluteFormHostOverride
40
+ {
41
+ get
42
+ {
43
+ if ( ! _enableInsecureAbsoluteFormHostOverride . HasValue )
44
+ {
45
+ _enableInsecureAbsoluteFormHostOverride =
46
+ AppContext . TryGetSwitch ( "Microsoft.AspNetCore.Server.Kestrel.EnableInsecureAbsoluteFormHostOverride" , out var enabled ) && enabled ;
47
+ }
48
+ return _enableInsecureAbsoluteFormHostOverride . Value ;
49
+ }
50
+ set => _enableInsecureAbsoluteFormHostOverride = value ;
51
+ }
52
+
38
53
// The following two lists configure the endpoints that Kestrel should listen to. If both lists are empty, the "urls" config setting (e.g. UseUrls) is used.
39
54
internal List < ListenOptions > CodeBackedListenOptions { get ; } = new List < ListenOptions > ( ) ;
40
55
internal List < ListenOptions > ConfigurationBackedListenOptions { get ; } = new List < ListenOptions > ( ) ;
Original file line number Diff line number Diff line change 11
11
using Microsoft . AspNetCore . Testing ;
12
12
using Microsoft . AspNetCore . WebUtilities ;
13
13
using Microsoft . Extensions . Logging ;
14
+ using Microsoft . Extensions . Primitives ;
14
15
using Moq ;
15
16
using Xunit ;
16
17
using BadHttpRequestException = Microsoft . AspNetCore . Http . BadHttpRequestException ;
@@ -140,6 +141,30 @@ public Task BadRequestIfHostHeaderDoesNotMatchRequestTarget(string requestTarget
140
141
CoreStrings . FormatBadRequest_InvalidHostHeader_Detail ( host . Trim ( ) ) ) ;
141
142
}
142
143
144
+ [ Fact ]
145
+ public async Task CanOptOutOfBadRequestIfHostHeaderDoesNotMatchRequestTarget ( )
146
+ {
147
+ var receivedHost = StringValues . Empty ;
148
+ await using var server = new TestServer ( context =>
149
+ {
150
+ receivedHost = context . Request . Headers . Host ;
151
+ return Task . CompletedTask ;
152
+ } , new TestServiceContext ( LoggerFactory )
153
+ {
154
+ ServerOptions = new KestrelServerOptions ( )
155
+ {
156
+ EnableInsecureAbsoluteFormHostOverride = true ,
157
+ }
158
+ } ) ;
159
+ using var client = server . CreateConnection ( ) ;
160
+
161
+ await client . SendAll ( $ "GET http://www.foo.com/api/data HTTP/1.1\r \n Host: www.foo.comConnection: keep-alive\r \n \r \n ") ;
162
+
163
+ await client . Receive ( "HTTP/1.1 200 OK" ) ;
164
+
165
+ Assert . Equal ( "www.foo.com:80" , receivedHost ) ;
166
+ }
167
+
143
168
[ Fact ]
144
169
public Task BadRequestFor10BadHostHeaderFormat ( )
145
170
{
You can’t perform that action at this time.
0 commit comments