I am trying to use the csrf guard project.
When wouldn't I want to protect a page from cross-site request forgeries (there is an option for protected and unprotected pages)?
In general the only reason why you wouldn't want csrf protection is because adding it breaks part of your website. Sometimes this might be because a specific page already has a different type of csrf protection on it.
Related
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.
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.
I know I am missing something, but please help me understand. Consider this situation:
I have a website called goodbank.com. URL http://goodbank.com/transfer/ serves a HTML page on GET with a form to transfer money to another account. The form has a random token to prevent CSRF attack. On the server, token validity is checked on POST and the corresponding controller allows only authenticated sessions.
Let's say that in my browser, I login to goodbank.com/. In another tab, I go to robgoodbank.com. As part of the served page, it has javascript to do AJAX request to goodbank.com/transfer/ to get a valid form. It then fills in other fields in the form and does a POST. My account is cleaned out :(
How does existing protection schemes protect against such an attack?
Thanks in advance.
Unless your server allows Cross Origin Resource Sharing, the browser will reject the XMLHttpRequest. As per the link, the XMLHttpRequest sends the Origin header containing the domain from which the request originates. If the server does not respond with Access-Control-Allow-Origin containing a wildcard of that domain, the browser will reject the request. There are actually a number of Access-Control- headers to control access including allowable methods, etc.
For extra protection, your server should check the Origin if it is present and the Referer HTTP header, which will be "http://robgoodbank.com" in your example, and you can also reject the request.
These are by no means foolproof, but do provide extra layers of protection. There are mechanisms (such as extensions) to spoof the Referer, but those would have been employed by the user unless their browser has been compromised in some way. If their browser has been compromised they are in a lot more trouble...
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.
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/