Thursday, April 23, 2015

Open Redirection Attack in MVC

In today's blog post I am going to discuss open redirection attack in MVC applications.

Open Redirection

Any application that redirects the user to a URL that is coming in as query string or form data can be vulnerable to open redirection attack.

If we try to visit a controller action with Authorize attribute and we are not logged in, we are redirected to the login page. This redirection looks like this:

/Account/Login?ReturnUrl=%2FExpense%2FIndex.


Once we login we are redirected to the /Expense/Index page, as mentioned by the ReturnUrl.

Imagine, if you received an email which has a hyperlink like this:

http://www.mygoodbank.com?ReturnUrl=www.mugoodbank.com  


(Please note the return Url has a different spelling). The Url might look similar but is controlled by the attacker.

So the user visits the page related to mygoodbank.com and enters the login name and password. Once the user enters the credentials, he is redirected to mugoogbank.com which the attacker has made sure that the page looks similar to the login page of my mygoodbank.com. The victim might think that he is redirected to the login page again because he mistyped the credentials. So the user types in the username and password again (this time on malicious website) and clicks on Login. The attacker can save the username and password and redirect the victim to the legitimate website. The legitimate website had already authenticated the user on previous attempt, so the user sees the required page that he was trying to access.

In this way, the attacker has stolen the user credentials without the victim ever knowing about it. Mixing a little social engineering with technical ability helps the attacker to accomplish this easily.

How To Prevent?

Whenever we redirect the user to any URL in our application, we must check that Url is local or not. If not, we must raise an exception that open redirection attack was attempted.

In MVC5, the AccountController Login method has:

return RedirectToLocal(returnUrl);


This RedirectToLocal tests whether the URL is local or not using Url.IsLocalUrl() method. Similarly, if we are redirecting the user to any page based on the input coming from the user, we should test if the URL is local or not.

Conclusion

MVC1 and MVC2 were vulnerable to this attack as they were not checking for the local URL. But MVC3 onwards, the AccountController checks for local Url. In our application, if we are redirecting anywhere we should make sure that the user is being redirected to local URL only.
For future updates to my weekly blog, please subscribe to my blog via the "Subscribe By Email" feature at the right and follow me on twitter. Until then Happy Coding :)

No comments:

Post a Comment