Do Login Forms Need Tokens Against Csrf Attacks

Should login forms be protected against CSRF?

You misunderstand how CSRF works.

No, an attacker can't just take any CSRF token. The CSRF token sent to different users differs. Taking an existing CSRF token then using that to try to trick a different user with that different token is going to fail because the token will not match what was already given to the browser the user is accessing the form with.

Not only is the token going to differ, the point of a CSRF token is that it is given to a user twice, in ways where an attacker can't access both values. The CSRF token is stored both in a cookie (preferably with HttpOnly set to True, so it is not even accessible to code running in the browser) and it is embedded in the form. When the form is submitted, the token posted with the form must match the token in the cookie.

So not only can't the attacker use an earlier CSRF token (which would differ already from what the user was given), the attacker also can't know what cookie the browser would have sent the user, nor can they ever access that cookie even if HttpOnly was not set, because an attacker on domain A can't read cookies for domain B.

Presumably you are using the Flask-WTF CSRF protection here (given the function name). This package stores CSRF tokens in the Flask session, and cryptographically signs tokens and attaches timeout, so an attacker can't replace the session with another that contains their own token, either. In addition, if your users are accessing the site over HTTPS, the HTTP Referer header must match the hostname that the client accessed.

As for the question if login forms, specifically, need to be protected with CSRF: Yes, because if an attacker can choose what login is used by the victim, they can then get access to whatever else the victim has entered into the site. By protecting your login form from CSRF attacks, you protect your users from this scenario.


Fun fact, I reported this issue to then-still-very-new Mozilla project in May 2000 to discuss how browsers could help to mitigate what is now known as CSRF, after having identified the issue on the Open Source Zope platform. Boy, that makes me feel old now.

Are anti-forgery tokens necessary on a login page?

Expanding on IRCMaxell's answer. CSRF is by definition meant to use a user's session and/or permissions against them. A non-authenticated user isn't the target of CSRF.

Here's a useful OWASP article on the subject: https://www.owasp.org/index.php/Cross-Site_Request_Forgery_%28CSRF%29

Placing anti-forgery tokens in login forms is almost entirely for consistency's sake.

EDIT:

That last statement I made was incorrect. Another answer here correctly pointed out that "Account Fixation" attacks are possible. This means that it's possible to log someone in to a site under credentials that are not their own. This can lead to the potential disclosure of personal or financial information.

That being said, the general practice of including CSRF validation for all your webforms is a useful and often necessary practice.

When its Necessary to Protect Forms with Token (CSRF attacks)?

Generally speaking, you want to protect your form anytime its submission will result in a change of content/state; be it adding it, removing it, editing it or sharing it with an external source ("share on xyz !").

An exemple of forms you wouldn't need to protect is a search box, since it doesn't result in any change of content.

If you're unsure, any form which will result in something being saved/deleted (whether it's on your site or not) should be protected.

And if you are really unsure just add the token, doesn't cost anything to be safe.

Is CSRF Protection necessary on a sign-up form?

No, for this specific situation not. A CSRF attack allows an attacker to exploit the rights that a victim has,
e.g. bank.com/pay?ammount=1000&to=34.67.978.246

It makes no sense to attack the log in form, since an attacker can log in by himself if he has the information that is required for a succesfull attack on the login field (the username and password).

The reason why Rails uses CSRF protection on the login field is simple: it's much more simple to implement CSRF protection globally than for 95% of the fields ;)

Are there reason why web devs dont use CSRF for login pages

CSRF involves silent exploits while the user is already logged in the browser (in another tab lets say).

If he is not, that request would not do anything, or simply reveal the attack by popping a login form.

So, to defend stupid web user from harming themselves, yeah I guess you could try to carry some antiCSRF token. But now, tell me how you begin that antiCSRF protection again? How could I possibly post my anticsrf token along the login form the first time? I would have to land on the / or something else to get the anticsrf token while receiving the login page. But most site have the login form straight in the first landing page. Hence the browser cannot present an antiCSRF token on first request (cannot use cookies, because it would be sent by browser even during the attacking request).

Anyway, that's my guess.

Do I need csrf tokens after login?

Well I'd say yes you have to do it, look at this excerpt taken from owasp ( Open Web Application Security Project ) documentation:

When targeting a normal user, a successful CSRF attack can compromise
end-user data and their associated functions. If the targeted end user
is an administrator account, a CSRF attack can compromise the entire
Web application. The sites that are more likely to be attacked are
community Websites (social networking, email) or sites that have high
dollar value accounts associated with them (banks, stock brokerages,
bill pay services). This attack can happen even if the user is logged
into a Web site using strong encryption (HTTPS). Utilizing social
engineering, an attacker will embed malicious HTML or JavaScript code
into an email or Website to request a specific 'task url'. The task
then executes with or without the user's knowledge, either directly or
by utilizing a Cross-site Scripting flaw (ex: Samy MySpace Worm).

How do I handle CRSF tokens for login pages?

Technically speaking, the login page is an out-of-session page (the user hasn't logged in yet) and therefore a CSRF mitigation isn't really needed. There's not a whole lot a hacker can do if the user hasn't established a session. I guess he could trick a user into logging on-- if he knows the user name and password-- but if could do that he could log in from his own browser instead.

If you insist on the CSRF token on the login page, I suggest you render the token as per usual and refresh the page with a Javascript timer (setTimeout) a few seconds before the token is due to expire.

Protecting login and comment forms against CSRF

The CSRF problem relates to someone using logged in user credentials to submit something. This is highly problematic as a malicious site can do stuff as anyone who's just browsed into your site. If you're talking about forms that can be used as anonymous, without logging in, there is lot less CSRF risk as there is considerably less to gain from posting to the form from another site - as anyone can do it directly also with same permissions.

So I don't get why protecting against CSRF for non-logged-in forms is needed.

If you do want this, a pre-session token could be technically similar to real session, but just a more light-weight one. It wouldn't really contain anything else than a generated token.


EDIT: about using the $_SESSION provided by PHP for the pre-session token, that's PHPs standard session mechanism. If you want to use that, then yes, that's about it.

However you're not forced to do it that way, and I personally wouldn't do it like that as it consumes server memory for all visitors, and that's not really needed. For a more efficient mechanism, basically you need a) a cookie identifying the user and b) something stored on the server side telling that the cookie is valid (and if needed, who is it valid for, meaning the ip). For a more light-weighted approach you can just create a token, store it in a cookie, and generate something matching that token in the form as hidden field, and match those on submit (like explained by Devesh). The latter would prevent submit of forms from another site, the former would prevent even the case where a malicious site does a lookup on your site and tries to set any cookies to the end user, too. So three approaches that I can think of:

  • just prevent image requests from other sites - using POSTs prevents this
  • prevent form submits from another site - form hidden field matching a cookie prevents this
  • prevent form submits from another site that do pre-lookup on your site - this would need IP verification, something stored on the server side, like ip in the database matched to the cookie

EDIT2: On captchas, their main use case is to prevent automated (brute force) login attempts. They would fix the issue with CSRF requests on login forms, too, but are an overkill for that. For preventing brute force login attacks they might be needed in some cases, although something more user friendly might be in order to not degrade usability too much. Maybe something like KittenAuth :)



Related Topics



Leave a reply



Submit