How does it happen?
- User logs in
- Our site sends back an authentication cookie
- On every subsequent request, the user’s browser will send the cookie back to our server and the server knows the user's agent (browser) is authenticated
Browser ---> Authenticate me ---> Server
Server --> OK, take this authentication cookie and supply to me on subsequent requests --> Browser
So far so good
- User goes to another site or tricked into picking HTML from another malicious site. Links in suspicious emails are a common way by which users are tricked.
- The malicious link puts up a page/form in the user's web browser that points to our site and posts a form with bad information. The form has all the inputs in the form to apply changes (recall that the user browser already has the authentication cookie previously obtained upon authentication).
- At the bottom of the malicious form, there is a script to automatically submit this form when the form POPs up.
- < form action=>..
- <div>
- < input...>
- </div>
- <script type=”text/javascript”>
- document.getElementById(“theForm”.submit());
- </script>
- The malicious request or form works against our Server because the browser has been previously authenticated
- Result: The user has just inadvertently submitted data on behalf of the malicious site
It is not enough to be authenticated
- In MVC, we use the Authorize attribute on HttpGets and HttpPosts to authenticate the user before the controller action proceeds any further
- GETs should not be used to update information on the Server; only POSTs should update information
- Our server should not only make sure the POST request is from an authenticated browser but it must also make sure the form being posted originated from our server.
- Therefore, we must check that the information being submitted is from a FORM our Server provided to the browser
Use the Html Anti-forgery token in MVC Forms
- An Html helper adds hidden input to the form with a value unique to user’s browsing session
- A matching value (anti-forgery token) is sent as a cookie to user’s browser
- Malicious user is not able to manipulate cookies for your server domain
- The Anti-forgery token will comes back during authenticated postback
// Razor code
@using (Html.BeginForm())
{
HtmlHelper.AntiforgeryToken();
@Html.ValidationSummary(true);
...
}
- To enforce the anti-forgery token, an ValidateAntiForgeryToken attribute must be applied to POST controller action
[HttpPost]
[Authorize]
[ValidateAntiForgeryToken] // make sure form value and cookie values match
// Valid only for POST verb
public ActionResult Edit(Review review)
{
...
}
- Now the malicious popup will get an error from ASP.Net: A required anti-forgery token was not supplied or was invalid.