Are both csrf tokens and captcha needed? - forms

Can someone confirm this: do I need to provide both a CSRF token and a Captcha in a submission form, or do the two more or less serve the same function (one can be used instead of the other)?

A captcha can be used instead of a CSRF token. This is covered in the OWASP CSRF Prevention Guide. A Captcha is considered to be a stronger form of CSRF prevention than a token or referer check because it is more difficult to bypass with XSS - but still possible. So long as the captcha cannot be replayed by a different browser than what loaded the captcha.
Any SOP bypass may be used to read the Capthca's challenge-response and feed it to an attacker to solve in order to complete the request. Even in this attack scenario, a CSRF token wouldn't help you, and a Captcha is still more difficult to exploit but not impossible.

Yup I was wrong. Both captcha and token are session-bound.
However I still see not much sense in this question.
You cannot use CAPTCHA for the every form on the site. It will drive users crazy and away.
Thus, why not to have a token for the every form by default and CAPTCHA for selected ones?

The above suggests the answer is "no".
But in reading about CSRF tokens compared to CAPTCHA it's worth looking into this, which says:
"CAPTCHA does not prevent cross-site request forgery (CSRF)":
https://blog.detectify.com/2017/12/06/captcha-csrf/

Related

CSRF token timeout

This page describes a use case to explain CSRF attacks (16.1):
https://docs.spring.io/spring-security/site/docs/current/reference/html/csrf.html
But if the user is indeed logged in the bank's website, then isn't it possible for the evil website to make a GET request to get a fresh CSRF token, and craft a POST without needing the user at all?
The answer must be no, otherwise CSRF token would be useless, but I don't understand why?
The answer is "no" and the reason is Same-Origin Policy.
SOP means that a page from evil.com cannot read any response to requests that it may send to example.com. Most direct means to send a request will be blocked by the browser (SOP), but there are many workarounds. For example, evil.com could send
GET requests by imbedding an <img>, <script>, <css> and setting src="http://example.com/path" (or <a href="http://example.com/path">).
POST requests by submitting a form.
Since evil.com cannot read any of the responses, it cannot read the CSRF token.

CSRF token protection using cookie

Is it a good practice to save the csrf token in a cookie or is it better to use a hidden field in a form? Also is it good to regenerate csrf token every user request like what captchas are doing?
Thanks
It is best to include it in the form. The idea behind a CSRF token is that it is not passed passively (e.g. if a malicious user is able to trick the browser into accessing some URL that does something nasty). Cookies are passed passively.
The best explaination to this question can be found on OWASP website at OWASP CSRF Prevention Cheat Sheet page.
Firstly, using cookie for a CSRF token can not help much because all cookies, even the secret ones, will be submitted with every request. All authentication tokens will be submitted regardless of whether or not the end-user was tricked into submitting the request.
Secondly, the application can include hidden input parameter in the form with a common name such as "CSRFToken". The value of this token must be randomly generated such that it cannot be guessed by an attacker.
Furthermore, Challenge-Response is another defense option for CSRF. It can be implemented in following ways:
CAPTCHA
Re-Authentication (password)
One-time Token
The CSRF cookie is certainly open to attack but implementation safe as the session value will always be checked against a submitted token value either stored in the body or header of the request so I can't see a reason against. The double submit (http only cookie vs post data) or token synchronizer (session vs post data) patterns outlined on the OWASP website are good pratices and both use cookies.
Double submit as mentioned earlier moves the storage to the client so is considered stateless but either way two tokens for comparison, of which one always remains unknown to the attacker.

Does CSRF defense also defend against clickjacking?

Suppose my web app is protected against a CSRF attack with a CSRF token, and, in addition, it uses SSL and is protected against XSS attacks. Also, for the purposes of this question, suppose it's used only from recent browsers and that they have no bugs. I can protect against frame-based clickjacking with an X-Frame-Options:Deny header, but I don't see what additional protection it would be providing, as any frame-based form submission would be lacking the CSRF token. (And the same-origin policy prevents the CSRF token from being discovered by the attacker's JavaScript.) Questions:
Is there some other kind of clickjacking that's not frame based? (I.e., is an X-Frame-Options:Deny not a complete clickjacking defense?)
In the absence of an X-Frame-Options:Deny header, is it still possible for a clickjacking attack to succeed given the above assumptions?
(I'm asking this not because I want to prevent frame-based clickjacking, because I do include the X-Frame-Options:Deny header. Rather, I'm trying to understand how the scope of clickjacking attacks.)
Doing some more research, I think I have answered my own question: The overlaid, transparent iframe holds the site to be attacked, accessed normally. For example, it might be a page with a button to delete photos, emails, etc. The visible page, from the attacker's site, is something else entirely, perhaps for entering a contest, with a button positioned exactly where the iframe button is. So, this is not a case of CSRF, because the form submitted is not a forgery; it's real in every way, and hasn't been altered.
The solution is to disallow the site from being loaded into a frame, which is what X-Frame-Options:Deny does.

CSRF protection of GET links

I need to add CSRF protection to a web application.
Problem is in the fact that the app relies heavily on links (GET requests that is) to make changes in the database.
Links are generated using a class, so I could easily add an extra parameter for CSRF token to each link.
However, I understand that CSRF token in a GET request might not be a good enough protection.
Note that app is only available over HTTPS, so GET params can not be exposed/stolen during client/server communication (but history stealing issue remains).
Could GET CSRF token param be considered "safe enough" in this setting?
If not, what is the best way to solve this problem? Only thing that comes to my mind is to wrap each of my links into a form (ether explicitly, or creating form onSubmit using JavaScript).
To be able to read the response to a CSRF attackā€™s request, an attacker would need to get the victim to execute his JavaScript code. So, CSRF for a "GET" request is almost not useful. This is assuming you have followed the standards that "GET" requests should not modify any data and any modifications need to be done only using "POST"
Using cookie based authentication and SSL should keep you away from a guy who is trying to change the parameters
You may want to introduce some signing based on timestamp to avoid replay attacks
That said, if you have any POST requests, you should consider the CSRF protection.

What exactly triggers the "Form authenticator is invalid" exception on PFG-forms?

Every once in a while the submit of a PloneFormGen-form (it happens on different forms, so nothing form specific) raises the "Form authenticator is invalid" exception.
I know this is the Cross-Site Request Forgery (CSRF) protection going off, but what is that exactly?
What triggers it and how can it be prevented (because, as far as i can tell all the triggering submits were valid, so no forgery going on :-)
Thanks!
To protect against from posts from other sources, many Plone forms, including PFG forms where you haven't turned it off, contain a cryptographic token as a hidden input. That token must be present in the submit, and the submit must be by HTTP POST.
When CSRF protection is turned on, a submit from any other source than the original form will trigger an error. You could also conceivably get the error if one user loaded the form, then in the same browser logged in as another user. Or, if the post was turned into a GET by a proxy or browser plug in.
You can turn off CSRF checking in PFG on a form-by-form basis. CSRF checking isn't really useful unless some valuable resource is being protected.