13

Mission:

To prevent open redirection in an ASP.NET MVC 5 application

The story:

The user is on some webpage of website /, say overview page /Home/Overview and clicks login

After login, the server returns some top-secret user specific data and redirects to the same page from where the user initiated login request.

I need to make sure that the server do not stupidly redirect to a hacker's website after login and also pass top-secret user specific data.

The values of

  • _Controller.Request.UrlReferrer
  • _Controller.Request.UrlReferrer.AbsoluteUri
  • _Controller.Request.Url.AbsoluteUri
  • _Controller.Url.IsLocalUrl(returnUrl)

respectively are:

  • {https://localhost:44300/Home/Overview}
  • "https://localhost:44300/Home/Overview"
  • "https://localhost:44300/Account/Login?returnUrl=%2FHome%2FOverview"
  • false

values for redirection

The value of Url.IsLocalUrl is false which is logically wrong.

In such case, how do I make sure that the user get safely redirected to /Home/Overview and not http://blackHatHackerWebsite.com after successful login?

Why Url.IsLocalUrl is false for local URLs in ASP.NET MVC?

Community
  • 1
  • 1
Zameer Ansari
  • 28,977
  • 24
  • 140
  • 219

2 Answers2

7

Url.IsLocalUrl("/Home/Overview") is definitely true. You get false because it's evaluating Url.IsLocalUrl("%2fHome%2fOverview"). That is, you returnUrl is url encoded twice. Try to find where you have an unnecessary encode.

Cheng Chen
  • 42,509
  • 16
  • 113
  • 174
  • I may be not doing any dual Url encoding. Btw, I'll surely review my code. Thanks!! Btw, I'm reading the [posts](http://stackoverflow.com/questions/34714789/why-url-islocalurl-is-false-for-local-urls-in-asp-net-mvc/34715197#comment57176098_34714789) referred by [@karthiksubramaniam](http://stackoverflow.com/users/4018620) – Zameer Ansari Jan 11 '16 at 06:14
  • Not sure where is double encoding is. was not able to check if the url is local using this, I would love to see an example. – Avi Dec 07 '16 at 19:07
-1

You can use the ping method If the result of the received ping address was successful That is, the address sent in the ReturnUrl variable is fake

// ` If reply.Status == IPStatus.Success`
//This means that the address entered in ReturnUrl is not local

private async Task<bool> ping_url(string url)
{
    Ping pingSender = new Ping();
    string host = url;
    bool res = true;
    await Task.Run(() =>
    {
        PingReply reply = pingSender.Send(host);
        /// if IPStatus.Success 
        if (reply.Status == IPStatus.Success)
            res = true;   
        else  
            res = false;  
    });

    return res;
}
Lee Taylor
  • 7,761
  • 16
  • 33
  • 49
jamaljaj
  • 27
  • 4