CORS explained briefly
understand cors in 5 minutes
There are some topics that we don't really like to address when it comes to development, and security is one of them. They are often positions held by different roles that are not necessarily compatible. 😅
Developers are like construction workers, they want to build things, security specialists are there to remind them that they need to wear their safety equipment and that they need to put up sturdy enough railings on the balconies, even if it's less pretty.
The CORS mechanism is one of those barriers that we shouldn't forget to put in place.
Okay, but what is this thing that's going to make me waste more time?
CORS: Cross-origin resource sharing
It's a configuration to be put on a service, for example a server that delivers an API, and which allows informing a browser whether or not it has the right to send its requests.
The key points:
- "browser": this mechanism is only addressed to web browsers
- "allows to inform": the server does not block anything, it "informs"
- "cross-origin": this only applies if the web application and the API do not share the same origin (www.example.com → smol.cats.com)
Concretely, if the web application needs to do a fetch to a URL whose origin is different from the address that allowed access to this site, the browser will make a preflight request, the server will respond with the authorized origins, the methods or other parameters (it informs) and the browser will decide whether or not to go further. From the point of view of the JavaScript application, the request is not sent at all and an error is directly returned.
Let's take an example, the site is accessed via https://my.awesome.app, it makes requests to /api/amazing and the server is configured and only authorizes origins coming from smol.cats.com. The browser will allow the request because it comes from the same origin (my.awesome.app → my.awesome.app/api/amazing), this is not "cross-origin".
One last point, it won't block requests made with cURL or a Node or Python application, since there is no origin and we are not in a browser. But you can still check it with cURL:
curl -H "Origin: https://my.awesome.app" \
-H "Access-Control-Request-Method: GET" \
-X OPTIONS \
--verbose \
https://smol.cats.com/api/cute
which returns this:
* Host smol.cats.com was resolved.
* IPv6: (none)
* IPv4: 342.547.0.197
* Trying 342.547.0.192:3000...
* Connected to smol.cats.com (342.547.0.192) port 443
> OPTIONS /api/cute HTTP/1.1
> Host: smol.cats.com
> User-Agent: curl/8.5.0
> Accept: */*
> Origin: https://my.awesome.app
> Access-Control-Request-Method: GET
>
< HTTP/1.1 204 No Content
< access-control-allow-origin: https://smol.cats.com
< access-control-allow-methods: GET,HEAD,PUT,PATCH,POST,DELETE
< vary: Access-Control-Request-Headers
< content-length: 0
< Date: Mon, 23 Sep 2024 09:44:27 GMT
< Connection: keep-alive
< Keep-Alive: timeout=72
<
* Connection #0 to host smol.cats.com left intact
You can see the access-control-allow-*
in the response
Need more info? RTFM!

I hope you learned something, and if not, that it was still fun to read 😅.
See you next time!