How does AntiForgeryToken work

Nadir Talic picture Nadir Talic · Jan 31, 2011 · Viewed 14.6k times · Source

I'm in trying to protect from CSRF and have two scenarious:

  1. Doing POST from within another site and it fails when I enable AntiForgeryToken
  2. I have tried from my "malicious" Javascript (running on another site) to first do GET of the page, parse it and extract RequestVerificationToken and then do a POST. This also fails but it is unclear to me why?

Can anyone please explain why?

Answer

Trevor picture Trevor · Jan 23, 2014

Here's a good tutorial on CSRF:

http://youtu.be/vrjgD0azkCw

Here is the general gist: You are logged in to your bank's website. Your bank puts a cookie on your machine so it can authenticate you. Every time you make a request to (ie. load a page from) yourbank.com, the browser sends the cookie to the web server and the code on the web server checks the cookie to make sure you're authenticated. Great.

However, while the cookie hasn't yet expired, you check your mail and open an email from a Nigerian Prince telling you to click on a link. You click on it (who can resist) and instead of taking you to the page the Prince has described, the link takes you to this URL:

http://yourbank.com/transfer.aspx?amt=1000000&from=myAccount&to=princeAccount

Because you're already authenticated at your bank (through the cookie), it thinks you're actually asking to transfer the money, so it does it.

This is obviously a bit of a contrived example, but it gets the point across. More realistically, the link might submit a request that changes your email address on a forum website that you belong to or something, so that they can get access to it.

So NOW, on to answering your specific question:

One way to combat this (used by Ruby and .NET and others) is to include an anti-forgery-token. Basically, when you request a page, the server includes a hidden field with an encrypted value. And when you submit the form, the website looks at the cookie to make sure you're authenticated, but it also looks at the encrypted value that the browser sends and make sure it's valid. The encrypted token would realistically be a session id that your account is tied to. So the server sees the cookie, identifies you as user 123, and then checks the encrypted form field token, decrypts the value and makes sure that unencrypted value matches your session or user id or something. If it does, it knows to proceed.

The Nigerian prince who sent you the link won't know what your session id is, and even if he did, he wouldn't be able to encrypt it with the same key and algorithm that the website is using.

And there you have it. Thwarting Nigerian princes one anti-forgery-token at a time.

(Nothing against Nigeria or Nigerians here. I'm sure they're lovely people. It's just their princes sometimes behave a bit poorly.) :)