Does a proper CORS setup prevent CSRF attack?
Asked Answered
D

7

85

If CORS is properly setup on a server to only allow a certain origins to access the server,

Is this enough to prevent CSRF attacks?

Doyen answered 5/11, 2013 at 16:19 Comment(3)
Good to read: security.stackexchange.com/a/97938/108639 and poshai.medium.com/are-csrf-tokens-necessary-3a6976bf1f34Gouge
Another good read: nodeployfriday.com/posts/cors-cyber-attacksChamperty
Related question about the topic of alternative-to-CSRF-token: security - Is checking the referrer enough to protect against a CSRF attack? - Stack OverflowArianearianie
M
78

To be more specific, it is easy to make the mistake of thinking that if evil.example cannot make a request to good.example due to CORS then CSRF is prevented. There are two problems being overlooked, however:

  1. CORS is respected by the browsers only. That means Google Chrome will obey CORS and not let evil.example make a request to good.example. However, imagine someone builds a native app or whatever which has a form that POSTs things to your site. XSRF tokens are the only way to prevent that.

  2. Is it easy to overlook the fact that CORS is only for JS request. A regular form on evil.example that POSTs back to good.example will still work despite CORS.

For these reasons, CORS is not a good replacement for XSRF tokens. It is best to use both.

Mccollum answered 5/5, 2016 at 8:11 Comment(7)
If I'm not mistaken, your first point may be invalid -- since CSRF attacks only work on browsers.Costumier
#2 does apply. CORS only prevents the browser from making XHR requests. If the site changes the location URL (e.g. a native form POST or a link for a GET) then CORS does not apply.Kinsfolk
@pace we're saying the same thing. I wrote "CORS is only for JS request" and you wrote "CORS only prevents ... XHR requests".Mccollum
Yes, sorry. I could have been more clear. I was disputing @Benja’s claim in the above comment. I agree with your answer @MccollumKinsfolk
I see, you're right the request would still be sent. but what I meant is that if you whitelist using the Origin header, then those cases (form submit or navigate) would be stopped, as they don't send an Origin header, which is a much simpler check than implementing XSRF tokens.Sheasheaf
to elucidate @Costumier answer, CSRF attack requires a user to be logged onto good.com. And that only happens on a browser.Samora
CORS is only for JS request. That statement is incorrect/imprecise. You can send some cross-origin requests using fetch without triggering CORS preflight; see twitter.com/jub0bs/status/1432025056234835980Portillo
C
19

No.

The Same Origin Policy (which CORS allows you to punch selective holes through) prevents third party sites from masquerading as a user in order to read (private) data from another site.

A Cross Site Request Forgery attack is when a third party site masquerades as a user to submit data to another site (as that user). It doesn't need to read the response back.

Cognition answered 5/11, 2013 at 16:29 Comment(5)
But it could, right? CSRF-get's for instance <img src=victim.bank/check.png?account=...> to get a check photo from a vulnerable bank site, without generating origin headers or preflighted requests. [...] The photos will be displayed, and the attackers can get the photo data using Javascript and send them back. source,Aquarelle
Your assumption that CSRF attacks are limited to "submitted" data seems to be wrong. And, further, that CSRF couldn't remedy this situation is also wrong (though ymmv with even modern browsers), If the browser checks the Access-Control-Allow-Origin header in the response and refuses to display it, it will be an effective defense. (same source)Aquarelle
@EvanCarroll — In response to your first comment: Using an image like that can trigger a CSRF attack. CORS can't prevent that for the reasons described in this answer. The attacker can display the image to the user (which might be useful in phishing attacks) but they cannot make the browser send a copy of the image (or data extracted from the image) to the attacker (because the Same Origin Policy prevents it). Your source is wrong.Cognition
@EvanCarroll — In response to your second comment: Data submitted to a server by embedding it in a query string of a URL that is loaded via an image tag is still submitted. "If the browser checks the Access-Control-Allow-Origin header" — No browser does that, so it isn't relevant in a discussion about authoring websites. "it will be an effective defense" — The Same Origin Policy is already an effective defence against other sites finding out information about what images a user has access to on a server.Cognition
Nice answer, but I think 'Same site policy' has more things to do other than 'just preventing masqueraded Read'. It also prevents PUT and DELETE verbs.Lomeli
M
10

No!

CORS enables sharing between two domains where XSRF is attacking method that does not depend on CORS in anyway.

I don't understand what you mean by "CORS is properly setup" but when attacking with XSRF, browser don't ask for CORS headers on server.

CORS is not security :)

Myer answered 5/11, 2013 at 16:25 Comment(4)
It should be put up in big bold letters: "CORS is not security!" CORS only specifies what types of cross-origin requests are allowed to your server. It shouldn't be a substitute for good security practices.Disarmament
I guess what I'm trying to get at is can anyone spoof an origin header? If so wouldn't CORS or the Same-Origin-Policy break down?Doyen
@Doyen A hacked or compromised browser could lead to that situation. The philosophy behind CORS relies on the user's browser being trusted.Kinsfolk
answer doesnt say why or how, XSRF/CSRF is to make a illegitimate request on user behalf. siteA calling siteB/logout for example. Strict CORS policy prevents cross site JS calls, so how come.Ruder
A
8

Maybe

Man this is a tough one, and it's far more complex than the others have provided for. So "maybe"

First, CORS is intended to "relax" same-origin-policy which is a default that prevents a specific type of CSRF attack. But, same-origin doesn't apply on all kinds of requests.

So the longer the session needs to time out and the more the user surfs around untrusted sites, the higher the risk is to pop onto one with a CSRF attack on it. Any tag which fires a request to an external resource can be used to perform a hidden CSRF attack – including images, link tags, some meta tags, embed and object tags and so on. Same goes for attributes which load background images or similar. You can even check if you site has been validated by someone if you replace the DTD file in the very header of the applications markup with a resource on your servers – that’s CSRF too. source

For an example of that, check this..

<img src=victim.bank/check.png?account=...>; to get a check photo from a vulnerable bank site, without generating origin headers or preflighted requests. [...] The photos will be displayed, and the attackers can get the photo data using Javascript and send them back. source

However, at least one source suggests that perhaps in the future web servers will return images with Access-Control-Allow-Origin (CORS) headers on images that will stop browsers from rendering the image. This will prevent CSRF-GET attacks of this sort..

If the browser checks the Access-Control-Allow-Origin header in the response and refuses to display it, it will be an effective defense. source

Aquarelle answered 14/4, 2015 at 19:18 Comment(3)
"the attackers can get the photo data using Javascript and send them back" — That is not trueCognition
When I run that code, after replacing the URL with an image on a different origin, the browser console says: Uncaught SecurityError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data. So, no, it isn't possible because the Same Origin Policy kicks in.Cognition
@Cognition Look at your network tab, it didn't prevent the request from being made, it only prevented you from accessing the data, but wouldn't prevent a modification from occurring if the request modified data. This should still be safeish since a GET request shouldn't modify data.Kinsfolk
N
6

Proper CORS Setup

The modern browsers try to prevent the Cross-origin request forgery attack with a security mechanism aka SOP (Same Origin Policy).

The CORS settings is going to open some restrictions of the SOP and relaxing that.

I would Interpret The Proper CORS Setup to having:

  • a browser with SOP feature
  • allow cors headers to not be * or <request-origin-host> (just being the hosts which are trusted)

SOP Restrictions

if any page requests for cross-origins, there are 3 policies:

  1. write-request like: link, redirects, xhr, form submitions (allow) (Rule 1)
  2. embeding-request like: <script>, <link>, <img>, <video>, <audio>, <object>, <embed>, @font-face, <iframe> (allow) (Rule 2)
  3. read requests (disallow) (Rule 3)

Among the above the first option (write-request) are subject to abuse for cross site request forgery.

The SOP mechanism just ALLOWED these write requests

Why?

  • for backward compatibility with the existing websites
  • convenient development & usage (just think if there exists a complex solution for a redirection what would happened!!! )

The only help that the Browser SOP does for this step is to send a pre-flight request for the resource-changing (POST/PUT/...) XHR requests

note: in future steps it will helps more than this

in the pre-flight request, the server sends the CORS Allow Header and browser finds out that if the resource changing request is allowed or not.

for example: if there is a form with post method which change a resource on server, the CORS Allowance Header will get received from server, but resource on server already has been changed. (antidote after sohrab's death )

SOP will prevent CSRF attack on xhr requests & not the application/x-www-form-urlencoded requests

  • there can be a form on evil.example or an script can append a form in DOM and automatically sending that.

or the xhr preflight it self may not prevent as we expected because:

  • in some browser it can be disabled because of performance (not having 2 requests)
  • if Origin header not set
  • Server may allow *
  • some bugs on preflight request expose the functionalities ...

CSRF-Token Mechanism

CSRF token can be used on both form and xhr requests.

CSRF-token mechanism prevents the CSRF attack if only if CSRF Token not exposed to cross-origin malicious scripts

but this scenario can be imaginable that: an script on malicious website:

  • first request for the form (aka edit form or delete form) & get the token
  • then send the token with application/x-www-form-urlencoded or xhr

SOP Supports CSRF-token

I have mentioned that SOP Restricts The Read request. and only allowed the read requests which are embeded.

so SOP will prevent the CSRF-token to get exposed by an malicious script (getting the form & creating a fake form with the token) if:

  • Proper CORS Setup
  • the form cannot get embedded

TL;DR

The SOP mechanism (with Rule #1) (Proper CORS setup) can prevent only CSRF xhr (can have some flaws in implementations) (canot protect all scenarios)

The CSRF-Token can protect CSRF Attack if the token hasn't get compromised

The SOP mechanism (with Rule #3) can protect CSRF-token & CSRF-token protect users from CSRF-attack

We should make attention to not compromise the CSRF-token with embedded resource Rule (Rule #2). (mostly iframe abuse)

MDN How to block cross-origin access

  • To prevent cross-origin writes, check an unguessable token in the request — known as a Cross-Site Request Forgery (CSRF) token. You must prevent cross-origin reads of pages that require this token.
  • To prevent cross-origin reads of a resource, ensure that it is not embeddable. It is often necessary to prevent embedding because embedding a resource always leaks some information about it.
  • To prevent cross-origin embeds, ensure that your resource cannot be interpreted as one of the embeddable formats listed above. Browsers may not respect the Content-Type header. For example, if you point a
tag at an HTML document, the browser will try to parse the HTML as JavaScript. When your resource is not an entry point to your site, you can also use a CSRF token to prevent embedding.

Further Readings

Same Origin Policy

CSRF Token mechanisms (implementation in The Laravel)

Nth answered 16/10, 2021 at 17:20 Comment(0)
P
0

No, because:

  • CORS is about sharing resources with origins other than the server's own. So if anything, it increases security risks when enabled. By default (and without CORS), servers restrict cross-origin requests because of the Same-origin policy.

  • While the Same-origin policy offers some protection, it does not restrict form submissions from other origins. For example, if a user is signed into good-bank.com, and then visits crook-site.com, the latter could have a form similar to the below to perform an unblocked CSRF attack:

    <form action="https://good-bank.com/api/account" method="POST">
        <input type="hidden" name="Transaction" value="withdraw" />
        <input type="hidden" name="Amount" value="1000000" />
        <input type="submit" value="Click to collect your prize!" />
    </form>
    
  • In addition to form elements, more requests (so-called "Simple Requests") don't trigger a CORS preflight as browsers have historically allowed them. This includes a POST request with standard headers.

For recommended mitigations against CSRF, the OWASP cheatsheet is a good resource.

Pinna answered 17/7 at 3:22 Comment(0)
K
-4

Actually CORS does contribute to security. CORS helps a lot in relation to XSS and CSRF attacks between different hosts. If a website has an XSS vulnerability and the attacker wants to use it to send a malicious request to another webpage through xmlhttprequest, thanks to CORS he is not going to be able to.

Kerosene answered 19/5, 2014 at 18:53 Comment(1)
CORS doesn't provide any additional security here. Before the CORS spec, the same xhr initiated request would have been rejected outright by the browser.Labourer

© 2022 - 2024 — McMap. All rights reserved.