3

I recently peeked into the implementation of Url.IsLocalUrl() method which is widely used and recommended as one of the measures to use to prevent redirection attacks. I was surprised to see that this method returns false if I were to provide a complete url to one of actions of my controllers in my application.

For example, if my application is hosted at http://localhost:422 and if I were to specify a valid controller and action name such as http://localhost:422/home/index, I will get false. After looking at its implementation, I understood why. But isn't the implementation incorrect to begin with?

Should I implement my own IsLocalUrl()? Or should I continue using the current one?

Parth Shah
  • 2,060
  • 1
  • 23
  • 34

2 Answers2

2

If you review the article Preventing Open Redirection Attacks , you will see the the expected use of Url.IsLocalUrl() and ReturnUrl= is to do redirects to internal pages/resources on the same site, usually after a login.

The examples show that it expects you to use relative or partial urls for internal redirection, not fully-qualified urls.

The best practice will be for you to write your code like this:

//  http://localhost:422/?ReturnUrl=/home/index
// returnUrl == "/home/index"
if( Url.IsLocalUrl(returnUrl) )
{

... instead of this:

//  http://localhost:422/?ReturnUrl=http%3A%2F%2Flocalhost%3A422%2Fhome%2Findex
// returnUrl == "http://localhost:422/home/index"
if( Url.IsLocalUrl(returnUrl) )
{

If you are only using redirects on the same site (as recommended for safety on most applications that aren't bit.ly type sites), then you should be able to do it.

Use the existing Url.IsLocalUrl() , but pass partial url redirects.

Raul Nohea Goodness
  • 2,549
  • 23
  • 24
0

According to the Same Origin Policy, the host and port have to be the same.

In practice, you will see all modern web browsers will treat 2 urls with the same host w/different ports as different sites, whether it is reading cookies or executing scripts.

So it seems like the implementation of Url.IsLocalUrl() is correct.

Update: this answer is not applicable now, since the question has been updated to so that the 2 urls have the same host and port number.

Community
  • 1
  • 1
Raul Nohea Goodness
  • 2,549
  • 23
  • 24