File tree Expand file tree Collapse file tree 2 files changed +56
-4
lines changed Expand file tree Collapse file tree 2 files changed +56
-4
lines changed Original file line number Diff line number Diff line change 1- // Copyright (c) .NET Foundation. All rights reserved.
1+ // Copyright (c) .NET Foundation. All rights reserved.
22// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33
44using System ;
@@ -60,7 +60,7 @@ public virtual bool IsLocalUrl(string url)
6060 // url doesn't start with "//" or "/\"
6161 if ( url [ 1 ] != '/' && url [ 1 ] != '\\ ' )
6262 {
63- return true ;
63+ return ! HasControlCharacter ( url . AsSpan ( 1 ) ) ;
6464 }
6565
6666 return false ;
@@ -78,15 +78,30 @@ public virtual bool IsLocalUrl(string url)
7878 // url doesn't start with "~//" or "~/\"
7979 if ( url [ 2 ] != '/' && url [ 2 ] != '\\ ' )
8080 {
81- return true ;
81+ return ! HasControlCharacter ( url . AsSpan ( 2 ) ) ;
8282 }
8383
8484 return false ;
8585 }
8686
8787 return false ;
88+
89+ static bool HasControlCharacter ( ReadOnlySpan < char > readOnlySpan )
90+ {
91+ // URLs may not contain ASCII control characters.
92+ for ( var i = 0 ; i < readOnlySpan . Length ; i ++ )
93+ {
94+ if ( char . IsControl ( readOnlySpan [ i ] ) )
95+ {
96+ return true ;
97+ }
98+ }
99+
100+ return false ;
101+ }
88102 }
89103
104+
90105 /// <inheritdoc />
91106 public virtual string Content ( string contentPath )
92107 {
Original file line number Diff line number Diff line change 1- // Copyright (c) .NET Foundation. All rights reserved.
1+ // Copyright (c) .NET Foundation. All rights reserved.
22// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
33
44using System ;
@@ -288,6 +288,43 @@ public void IsLocalUrl_RejectsInvalidTokenUrls(string url)
288288 Assert . False ( result ) ;
289289 }
290290
291+ [ Theory ]
292+ [ InlineData ( "\n " ) ]
293+ [ InlineData ( "\\ n" ) ]
294+ [ InlineData ( "/\n " ) ]
295+ [ InlineData ( "~\n " ) ]
296+ [ InlineData ( "~/\n " ) ]
297+ public void IsLocalUrl_RejectsUrlWithNewLineAtStart ( string url )
298+ {
299+ // Arrange
300+ var helper = CreateUrlHelper ( appRoot : string . Empty , host : "www.mysite.com" , protocol : null ) ;
301+
302+ // Act
303+ var result = helper . IsLocalUrl ( url ) ;
304+
305+ // Assert
306+ Assert . False ( result ) ;
307+ }
308+
309+ [ Theory ]
310+ [ InlineData ( "/\r \n somepath" ) ]
311+ [ InlineData ( "~/\r \n somepath" ) ]
312+ [ InlineData ( "/some\n path" ) ]
313+ [ InlineData ( "~/some\n path" ) ]
314+ [ InlineData ( "\\ path\b " ) ]
315+ [ InlineData ( "~\\ path\b " ) ]
316+ public void IsLocalUrl_RejectsUrlWithControlCharacters ( string url )
317+ {
318+ // Arrange
319+ var helper = CreateUrlHelper ( appRoot : string . Empty , host : "www.mysite.com" , protocol : null ) ;
320+
321+ // Act
322+ var result = helper . IsLocalUrl ( url ) ;
323+
324+ // Assert
325+ Assert . False ( result ) ;
326+ }
327+
291328 [ Fact ]
292329 public void RouteUrlWithDictionary ( )
293330 {
You can’t perform that action at this time.
0 commit comments