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 @@ -603,7 +603,22 @@ private void ValidateNonOriginHostHeader(string hostText)
603
603
if ( ! _absoluteRequestTarget . IsDefaultPort
604
604
|| hostText != _absoluteRequestTarget . Authority + ":" + _absoluteRequestTarget . Port . ToString ( CultureInfo . InvariantCulture ) )
605
605
{
606
- KestrelBadHttpRequestException . Throw ( RequestRejectionReason . InvalidHostHeader , hostText ) ;
606
+ // Superseded by RFC 7230, but notable for back-compat.
607
+ // https://datatracker.ietf.org/doc/html/rfc2616/#section-5.2
608
+ // 1. If Request-URI is an absoluteURI, the host is part of the
609
+ // Request-URI. Any Host header field value in the request MUST be
610
+ // ignored.
611
+ // We don't want to leave the invalid value for the app to accidentally consume,
612
+ // replace it with the value from the request line.
613
+ if ( _context . ServiceContext . ServerOptions . EnableInsecureAbsoluteFormHostOverride )
614
+ {
615
+ hostText = _absoluteRequestTarget . Authority + ":" + _absoluteRequestTarget . Port . ToString ( CultureInfo . InvariantCulture ) ;
616
+ HttpRequestHeaders . HeaderHost = hostText ;
617
+ }
618
+ else
619
+ {
620
+ KestrelBadHttpRequestException . Throw ( RequestRejectionReason . InvalidHostHeader , hostText ) ;
621
+ }
607
622
}
608
623
}
609
624
}
Original file line number Diff line number Diff line change @@ -36,6 +36,21 @@ public class KestrelServerOptions
36
36
37
37
private Func < string , Encoding ? > _responseHeaderEncodingSelector = DefaultHeaderEncodingSelector ;
38
38
39
+ private bool ? _enableInsecureAbsoluteFormHostOverride ;
40
+ internal bool EnableInsecureAbsoluteFormHostOverride
41
+ {
42
+ get
43
+ {
44
+ if ( ! _enableInsecureAbsoluteFormHostOverride . HasValue )
45
+ {
46
+ _enableInsecureAbsoluteFormHostOverride =
47
+ AppContext . TryGetSwitch ( "Microsoft.AspNetCore.Server.Kestrel.EnableInsecureAbsoluteFormHostOverride" , out var enabled ) && enabled ;
48
+ }
49
+ return _enableInsecureAbsoluteFormHostOverride . Value ;
50
+ }
51
+ set => _enableInsecureAbsoluteFormHostOverride = value ;
52
+ }
53
+
39
54
// 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.
40
55
internal List < ListenOptions > CodeBackedListenOptions { get ; } = new List < ListenOptions > ( ) ;
41
56
internal List < ListenOptions > ConfigurationBackedListenOptions { get ; } = new List < ListenOptions > ( ) ;
Original file line number Diff line number Diff line change 8
8
using Microsoft . AspNetCore . Server . Kestrel . InMemory . FunctionalTests . TestTransport ;
9
9
using Microsoft . AspNetCore . Testing ;
10
10
using Microsoft . Extensions . Logging ;
11
+ using Microsoft . Extensions . Primitives ;
11
12
using Moq ;
12
13
using Xunit ;
13
14
using BadHttpRequestException = Microsoft . AspNetCore . Http . BadHttpRequestException ;
@@ -137,6 +138,30 @@ public Task BadRequestIfHostHeaderDoesNotMatchRequestTarget(string requestTarget
137
138
CoreStrings . FormatBadRequest_InvalidHostHeader_Detail ( host . Trim ( ) ) ) ;
138
139
}
139
140
141
+ [ Fact ]
142
+ public async Task CanOptOutOfBadRequestIfHostHeaderDoesNotMatchRequestTarget ( )
143
+ {
144
+ var receivedHost = StringValues . Empty ;
145
+ await using var server = new TestServer ( context =>
146
+ {
147
+ receivedHost = context . Request . Headers . Host ;
148
+ return Task . CompletedTask ;
149
+ } , new TestServiceContext ( LoggerFactory )
150
+ {
151
+ ServerOptions = new KestrelServerOptions ( )
152
+ {
153
+ EnableInsecureAbsoluteFormHostOverride = true ,
154
+ }
155
+ } ) ;
156
+ using var client = server . CreateConnection ( ) ;
157
+
158
+ 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 ") ;
159
+
160
+ await client . Receive ( "HTTP/1.1 200 OK" ) ;
161
+
162
+ Assert . Equal ( "www.foo.com:80" , receivedHost ) ;
163
+ }
164
+
140
165
[ Fact ]
141
166
public Task BadRequestFor10BadHostHeaderFormat ( )
142
167
{
You can’t perform that action at this time.
0 commit comments