Live data from Hacker News

Demystifying CORS

frontendian.co

31–40 of 50 posts

Re: Demystifying CORS

#31

Earlier quoted context omitted.

CORS was designed to mitigate e.g. the following attack: * You are logged at with service X, which uses a Cookie to store your authentication code. * Service X offers an endpoint to change your password, as well as an endpoint to retrieve your user account. * You visit malicious website Y, which uses JS to send requests to the "change password" and "view profile" endpoints of service X (which without CORS would be ac…

I've always found it interesting how there's a difference between actions the user initiated and those the user did not. You'd think that would be very challenging to enforce, given how flexible browser scripting is nowadays, but it seems to Just Work.

There isn't, though. It really is just the same origin policy at work (or, if you mean more abstractly, the website flagging them differently; you can still construct it into a curl call that will be indistinguishable, barring something like a varying CSRF token that requires the page to be loaded, but again, that can still be faked by loading the page, grabbing the token, and using it in the resulting cURL call).

But preventing PUT/POST/DELETE from other origins prevents other origins from making requests on the user's behalf. It also prevents the user from making those requests. It either has to be a GET (which is itself a security hole, but one necessary to the basic utility of the web and which -should- be okay provided people do indeed make GETs idempotent; it has been leveraged into JSON-P, a terrible unsafe hack, though), or it has to use CORS to preflight it.

Once you have CORS in place, it's still indeterminate as to whether the action was user initiated or not. It's just that a request originating from origin (X) has been allowed.

Re: Demystifying CORS

#32

Earlier quoted context omitted.

CORS was designed to mitigate e.g. the following attack: * You are logged at with service X, which uses a Cookie to store your authentication code. * Service X offers an endpoint to change your password, as well as an endpoint to retrieve your user account. * You visit malicious website Y, which uses JS to send requests to the "change password" and "view profile" endpoints of service X (which without CORS would be ac…

If you need CSRF tokens for forms, etc, then what does CORS give you above CSRF tokens?

CSRF tokens are usually only used for state-altering requests (POST, GET etc.), though one could use them for GET requests as well. The reason people don't do use CSRF for GET is that there's usually no risk involved when calling a GET endpoint from your browser, as it's not supposed to change the state of a resource in any way. And since an HTML form submission or included link will take the user directly to your API, there's no way for the attacker to extract the information afterwards (which is of course given if the attacker can make the request asynchronously via Javascript).

You can also use the "Referer" and "Origin" headers to defend your API against form submission from third-party websites without using any CSRF tokens (as browsers will include the URL/domain of the site from which the form was submitted), though there were numerous cases where browsers or e-mail clients didn't set these headers correctly, so if you really want to be sure the only way is to use a CSRF token. You can put that token e.g. in a JS-readable cookie, which will not be accessible on third-party websites but which you can read out via JS on your domain and then include in the POST/PUT/... request. If you want to run your code from different domains as well you will have to provide an endpoint from which users can get the CSRF token though (as Cookies from your API domain will not be readable there). You will then need to restrict that endpoint using CORS, as otherwise an attacker will be able to get a valid token and e.g. inject that into an HTML form which he/she can then submit.

So CORS and CSRF do different things, but for API-based apps that should be able to run on multiple (non-sibling) domains you need both mechanisms to ensure security (and CSRF needs CORS in that case to function).

Re: Demystifying CORS

#33
So if I manually pull up an about:blank page and start screwing around in the devTools console, what are my options for pulling in junk from, say, Wikipedia?

Is it only jsonp?

Re: Demystifying CORS

#34
post #4

This post never actually explains why any of this was needed. The closest it comes is this bit: "If [...] the same-origin policy for XMLHttpRequests relaxed, said services could now receive a deluge of DELETE, PUT, etc… requests from any origin" But why on earth is this a problem? And in any case those services always could receive requests from any origin, browsers aren't the only HTTP clients in the world. In the o…

Along with the other responses here, also check out the very brief OWASP documentation on CORS at this link. [1] Searching that site for CORS would also be helpful.

[1]: https://www.owasp.org/index.php/HTML5_Security_Cheat_Sheet#C...

Re: Demystifying CORS

#35
post #17

Earlier quoted context omitted.

People get confused because it's two requests, first the options one, then the normal one. Their web frameworks are largely built on single connection handling, but because CORS isn't used by many people it's often a tacked on afterthought. For example, in Rails they briefly made it impossible to manually handle Options requests (something that I fixed). Then there is the core weirdness of subdomains and security hea…

There aren't two requests; at least not normally. Preflight requests are only needed if you want to send unusual headers in your request or use HTTP methods other than GET or POST. See https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Simpl... But you make a good point about developers not caring about security. If I look at it from that perspective it totally makes sense. If you don't have any reason to care, C…

You're right.

I forgot about the simple requests angle because 100% of the requests I make are non-simple. I need custom headers and JSON Content-Types. Yet again why this area is so annoying.

Re: Demystifying CORS

#36

Earlier quoted context omitted.

I've always found it interesting how there's a difference between actions the user initiated and those the user did not. You'd think that would be very challenging to enforce, given how flexible browser scripting is nowadays, but it seems to Just Work.

There isn't, though. It really is just the same origin policy at work (or, if you mean more abstractly, the website flagging them differently; you can still construct it into a curl call that will be indistinguishable, barring something like a varying CSRF token that requires the page to be loaded, but again, that can still be faked by loading the page, grabbing the token, and using it in the resulting cURL call). Bu…

That's not entirely correct, as you can still create a form on page Y and have it submit a POST request to site X even if CORS is enabled, as CORS does only govern asynchronously triggered requests. So you still need CSRF to fully protect against malicious form submissions from third-party domains.

Re: Demystifying CORS

#37
post #22

Earlier quoted context omitted.

CORS allows you to whitelist what domains you accept certain requests from. This is a good thing. One thing I never understood really is why a webpage is able to load scripts from a different domain. That will I suppose remain a mystery to me forever. Imagine how many fewer ads and junk we might see.

this is a cool feature but the actual whitelist has to be held internally, in responding to an OPTIONS request, you can respond with * or concrete domain name. you can't return something like "www.example.com, www.foo.com" . if you want to whitelist multiple domains you have to resolve this server side and check the requesting domain against your list of accepted domains. this took me a little while to figure out.

Right - it is a good safety feature. Also worth noting that responding with a wildcard will not allow you to set cookies in the browser when using `withCredentials` in the client and `access-control-allow-credentials` on the server. You've got to return a specific origin (one that is a match in your whitelist)

Re: Demystifying CORS

#38
post #12

What I find perplexing is that for this and every other web technology, there doesn't seem to be a central comprehensive resource that explains it all in great detail. It's like we have to pick things up as we go along, from tidbits and articles here and there, not of it complete or comprehensive, and often there'll be little mistakes or misleading bits.

I think MDN is doing a great job of becoming the go-to resource for everything: https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

Absolutely. And many of their docs can be imported to Dash.app. :-)

Re: Demystifying CORS

#39
post #4

This post never actually explains why any of this was needed. The closest it comes is this bit: "If [...] the same-origin policy for XMLHttpRequests relaxed, said services could now receive a deluge of DELETE, PUT, etc… requests from any origin" But why on earth is this a problem? And in any case those services always could receive requests from any origin, browsers aren't the only HTTP clients in the world. In the o…

Yeah, this aspect of CORS is almost never properly explained.

First off, it's not about the authentication cookie. It would be simple enough for browsers to just omit cookies in cross-domain requests.

Here's an example of a real issue:

1. You have a network-attached storage device on your LAN.

2. Because the device is not accessible from the public internet, you have decided not to enable authentication. Anyone on the local network can issue requests.

3. You visit a malicious website.

4. That website's JS makes network requests to your device.

Basically, when you run JS in your browser, it's using your computer's network context. That context may have privileges that not everyone has (e.g. authentication based on source IP). You don't want random JS code to have those privileges.

Re: Demystifying CORS

#40
post #4

This post never actually explains why any of this was needed. The closest it comes is this bit: "If [...] the same-origin policy for XMLHttpRequests relaxed, said services could now receive a deluge of DELETE, PUT, etc… requests from any origin" But why on earth is this a problem? And in any case those services always could receive requests from any origin, browsers aren't the only HTTP clients in the world. In the o…

It's to protect against malicious sites, not malicious clients.

CORS prevents your browser from being an unwitting attack vector by an evil website.

Post reply on HN