Does CSRF defense also defend against clickjacking? - csrf

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.

Related

Stateless REST API with CSRF and XSS protection

Is it possible to protect stateless REST API from both XSS and CSRF attacks?
Currently, I'm using JWT token stored in secure/httpOnly cookie for stateless authentication. This should protect the API from most common XSS attack: stealing cookies with XSS-injected JavaScript and sending them to the attacker.
However, this doesn't protect the API from CSRF attack, where attacker would trick the authenticated user to follow a link to the particular web API call to actuate adverse transaction on behalf of the victim. How could I protect the API from this attack without introducing server side state?
Also, is it true XSS vulnerability would inheritedly allow CSRF type attack in the following scenario: Injected JavaScript would retrieve CSRF token from the client side state, DOM or the browser storage and prepare a malicious ajax call to the server. Browser would still automatically include the httpOnly cookie for the same origin request. Is there a way to get protected from this other than protecting from the XSS vulnerability in the first place?
Stateless anti-forgery tokens
The first question is about preventing CSRF without server-side state. The current approach for stateless anti-forgery tokens is the double submit cookie pattern.
CSRF attacks depend on the browser automatically sending the API's own cookies back to it, regardless of where the request originated. The attacker doesn't have or need access to the cookie contents. They only need to trick the user into loading malicious HTML. The double cookie pattern adds a new requirement: the attacker must know and separately send the contents of the anti-forgery cookie.
There are ways for an attacker to overwrite the anti-forgery cookie with their own. So you may want to look at some additional security hardening for this approach. Especially HMAC signing the anti-forgery token to prevent token substitution. Using HSTS and the __Host cookie prefix to ensure transport security and proper cookie scope. And having the client provide the anti-forgery token in a custom header.
The custom header ensures the request must be sent from JS, since HTML-tag-based CSRF attacks cannot set custom headers. Being sent from JS also triggers additional protections. For cross-origin requests it triggers SOP on the browser and CORS validation on the server. The server can also do basic Origin validation.
Regarding the scope of CSRF attacks, here is a note from the OWASP CSRF link at the top.
Forcing the victim to retrieve data doesn’t benefit an attacker because the attacker doesn’t receive the response, the victim does. As such, CSRF attacks target state-changing requests.
XSS question
Yes, an XSS attack could happen that way. Once a malicious script is loaded into JS, it has free reign to use anything accessible to Javascript. Including app code/memory, browser storage, and cookies. Even though HttpOnly cookies are not readable, they can still be sent in requests. A non-targeted attack might look for key data in locations used by popular frameworks. And might try to probe for popular/discoverable API frameworks on the server. A targeted attack means the attacker studied your system and crafted a custom payload for it.
The primary vector for XSS is unsanitized external data (user input, database values, etc.). To prevent XSS, check out these guidelines from OWASP. Of note is that front-end frameworks like Angular, React, Svelte, Vue, and others have built-in XSS protection. Because they sanitize data before rendering it. Example: an attacker enters an HTML string into an input. When it is later displayed, these frameworks HTML-encode the string. So left and right angle brackets are replaced with < and > and so on. This causes the browser to evaluate the string as text instead of runnable HTML. But you can still mess it up in different ways if careless.
XSS attacks can also come from external resources. Maybe a compromised CDN or NPM script. If your deployed code takes dependencies on NPM libraries, pay extra attention to NPM audit warnings. One attack pattern is to attach a small loader (easier to go unnoticed), which will fetch attack payloads at runtime. A CSP policy can help prevent this. Specify an allowed list of resources -- your app assets and API URLs -- and block all others. CSP can also prevent data exfiltration.
For both CSRF and XSS
For attacks on your API, you can additionally employ server-side mitigations. IP-based throttling / temporary bans, unusual activity grey-listing and alerting, etc.
For especially sensitive operations, one strategy is to use an escalated authorization. This could take the form of requiring the user to re-authenticate or use a 2nd factor like a one-time password. This can block automated attacks since it requires active user intervention.
To mitigate attackers using existing escalated authorizations (which may also be in a cookie or app memory), they can have short expirations and be limited to specific operations. To go even further, the approved operations + relevant data can be signed. This will prevent malicious scripts from reusing an escalation to execute the same kind of operation with different data. Even further, these sensitive operations can be idempotent. So if an attacker does resend already-executed operations, they will not cause any additional changes in the system.
Zooming out
Try to engineer your systems to be as uninteresting as possible to hackers. Use trusted external services for sensitive needs like credit cards and credentials. Ideally (from a security perspective) the hacking risk would be reduced to just data vandalism/loss. So in the worst case that a breach happens, it would have little long-term impact. And it could be recovered with common practices, including routinely tested backups. And then further mitigations added for the specific attacks used.
Tread especially carefully with user-to-user interaction. Since this adds more targets and pivot points for hackers -- your user base. The most security-conscious eyes should be on these pieces. Not only for technical dangers like user-to-user XSS attacks, but also social ones. Human weaknesses are the most well-known and easiest to exploit.
Lastly, there is no sense investing in mitigations which have low risk/consequences in your situation. So do not take everything here as a requirements checklist. It's not a complete list anyway. Focus on your biggest risks first. Reevaluate periodically.
You can generate a token (e.g. a UUID) and put it into the jwt token as well as send it back to the client. Then the client sends it during every each request in a header. Then the server can compare the token in the header and the token in the jwt token to make sure the request comes from the client who was aunthenticated.

How do CSRF tokens protect from malicious GET followed by POST in another tab

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

When wouldn't I want to protect a page from CSRF?

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.

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.

Are both csrf tokens and captcha needed?

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/