How does AntiForgeryToken work
Asked Answered
P

2

26

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?

Porky answered 31/1, 2011 at 15:43 Comment(2)
This site has some useful information and details: Prevent Cross-Site Request Forgery (CSRF) using ASP.NET MVC’s AntiForgeryToken() helperFavian
This explains it: levelup.gitconnected.com/…Vinylidene
R
7

For security reasons, you cannot retrieve content from another domain using AJAX.

Therefore, other sites cannot get your token.

Robinett answered 31/1, 2011 at 15:57 Comment(4)
So, basically, POST works cross-domain (thus you need AntyForgeryToken, to prevent from "blind" POSTs), but GET doesn't inherently. Right?Ripsaw
@emirc: Wrong. You can send any kind of request cross-domain, but you can't read the replies.Robinett
Oh, thanks. I understand. Therefore it is recommended to not alter any data in GET, e.g. GETs should be read-only... Thanks very much!!!Ripsaw
@emirc: As far as cross-domain security goes, there is no difference between POST and GET. The point of anti-forgery tokens is that you need to read a response before you can send a request.Robinett
A
83

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.) :)

Alinaaline answered 23/1, 2014 at 4:55 Comment(3)
This also work to prevent webscrapping? I mean, if you have a form, and somebody simulates the post of the inputs, to get the result... using my app as a service for them. The AntiForgeryToken will prevent the same as the Nigerian scamers ?Quittance
I don't think it prevents web scraping. The token doesn't prevent a page from being viewed. It prevents a page being viewed by someone who didn't intentionally request it. Or rather, someone who didn't request it.Alinaaline
your link example uses a GET request. but submitting a form that you later refer to normally uses a POST requestErythrism
R
7

For security reasons, you cannot retrieve content from another domain using AJAX.

Therefore, other sites cannot get your token.

Robinett answered 31/1, 2011 at 15:57 Comment(4)
So, basically, POST works cross-domain (thus you need AntyForgeryToken, to prevent from "blind" POSTs), but GET doesn't inherently. Right?Ripsaw
@emirc: Wrong. You can send any kind of request cross-domain, but you can't read the replies.Robinett
Oh, thanks. I understand. Therefore it is recommended to not alter any data in GET, e.g. GETs should be read-only... Thanks very much!!!Ripsaw
@emirc: As far as cross-domain security goes, there is no difference between POST and GET. The point of anti-forgery tokens is that you need to read a response before you can send a request.Robinett

© 2022 - 2024 — McMap. All rights reserved.