I'm running a rather large site with thousands of visits every day, and a rather large userbase. Since I started migrating to MVC 3, I've been putting the AntiForgeryToken in a number of forms, that modify protected data etc.
Some other forms, like the login and registration also use the AntiForgeryToken now, but I'm becoming dubious about their need there in the first place, for a couple reasons...
The login form requires the poster to know the correct credentials. I can't really think of any way an CSRF attack would benefit here, especially if I check that the request came from the same host (checking the Referer header).
The AntiForgeryToken token generates different values every time the page is loaded. If I have two tabs open with the login page, and then try to post them, the first one will successfully load. The second will fail with a AntiForgeryTokenException (first load both pages, then try to post them). With more secure pages - this is obviously a necessary evil, with the login pages - seems like overkill, and just asking for trouble.
There are possibly other reasons why one should use or not use the token in ones forms. Am I correct in assuming that using the token in every post form is overkill, and if so - what kind of forms would benefit from it, and which ones would definitely not benefit?
P.S. This question is also asked on StackOverflow, but I'm not entirely convinced. I thought I'd ask it here, for more security coverage
Yes, it is important to include anti-forgery tokens for login pages.
Why? Because of the potential for "login CSRF" attacks. In a login CSRF attack, the attacker logs the victim into the target site with the attacker's account. Consider, for instance, an attack on Alice, who is a user of Paypal, by an evil attacker Evelyn. If Paypal didn't protect its login pages from CSRF attacks (e.g., with an anti-forgery token), then the attacker can silently log Alice's browser into Evelyn's account on Paypal. Alice gets taken to the Paypal web site, and Alice is logged in, but logged in as Evelyn. Suppose Alice then clicks on the page to link her credit card to her Paypal account, and enters her credit card number. Alice thinks she is linking her credit card to her Paypal account, but actually she has linked it to Evelyn's account. Now Evelyn can buy stuff, and have it charged to Alice's credit card. Oops. This is subtle and a bit obscure, but serious enough that you should include anti-forgery tokens for the form action target used to log in. See this paper for more details and some real-world examples of such vulnerabilities.
When is it OK to leave off the anti-forgery token? In general, if the target is a URL, and accessing that URL has no side effects, then you don't need to include anti-forgery token in that URL.
The rough rule of thumb is: include an anti-forgery token in all POST requests, but you don't need it for GET requests. However, this rough rule of thumb is a very crude approximation. It makes the assumption that GET requests will all be side-effect-free. In a well-designed web application, that should hopefully be the case, but in practice, sometimes web application designers don't follow that guideline and implement GET handlers that have a side effect (this is a bad idea, but it's not uncommon). That's why I suggest a guideline based upon whether the request will have a side effect to the state of the web application or not, instead of based on GET vs POST.
External links referenced by this document:
Local articles referenced by this article: