TIL how CORs work
POSTED ON:
TAGS: security vulnerability webdev
What the heck is Access-Control-Allow-Origin: *
?
It's CORs. And here's why we use it:
Because cookies sucked #
Back then, we did security credentials with cookies.
Credentials allow the server to maintain state about a particular user across multiple requests. It's how Twitter shows you your feed, it's how your bank shows you your accounts.
But that also means, I can do stuff like this.
<img src="https://your-bank/your-profile/you.jpg" />
To use a hypothetical:
- You log into your bank and it saves a cookie that you have access.
- You visit my malicious site, with that
malicious element
. Thatmalicious element
points to an image that you can ONLY SEE if you have a cookie on your bank's website. - If that image loads or fails, fire off a JS event.
Okay now CORS #
So we kinda need images to work regardless of what site they're on. I should be able to steal a image from your website and host it somewhere else. Same with JS code (Like CDNs!) But we also don't want the problem above where I can test your cookies.
The solution they came up with the HTTP Header opt-in:
The proposal by the Voice Browser Working Group was generalised using HTTP headers, and that became Cross-Origin Resource Sharing, or CORS.
By default, a cross-origin CORS request is made without credentials. So, no cookies, no client certs, no automatic Authorization header, and Set-Cookie on the response is ignored.
To pass the CORS check and give the other origin access to the response, the response must include this header:
The best way to figure it out is to try it and look at network DevTools. In Chrome and Firefox, cross-origin requests are sent with a Sec-Fetch-Mode
header which will tell you if it's a CORS request or not. Unfortunately Safari hasn't implemented this yet.
Too long didn't read #
If a resource never contains private data, then it's totally safe to put Access-Control-Allow-Origin: *
on it.
If a resources sometimes contains private data depending on cookies, it's safe to add Access-Control-Allow-Origin: *
as long as you also include a Vary: Cookie
header.
If you're 'securing' the data using things like the sender's IP address, or by assuming you're safe because your server is limited to an 'internal' network, it isn't safe to use Access-Control-Allow-Origin: *
at all. The data isn't actually secure. Platform apps will be able to get at that data and send it wherever they want. (remember, the 's' in 'IoT' stands for security)
https://getpocket.com/read/3456172786
Related TILs
Tagged: security