DEV Community

rndmh3ro
rndmh3ro

Posted on • Originally published at zufallsheld.de on

TIL how to test CORS on the command line with curl

In my last TIL I talked about how to set additional security headers for Gitlab. But I also had to do this for other applications I was supporting, where it was more straight-forward to do it (meaning: with code).

I needed to set the access-control-allow-origin header in the other applications. This header tells the browser from which origins the website is allowed to download resources.

This is relevant in web apps that run on webapp-frontend.example.com and want to use data from webapp-backend.example.com. To allow the browser to access webapp-backend.example.com, the frontend application needs to allow it in its access-control-allow-origin header, like this:

access-control-allow-origin: https://webapp-backend.example.com

Enter fullscreen mode Exit fullscreen mode

So I set this in the frontend-application and wanted to test it from the command line.

Here’s how I did it:

curl -v --request OPTIONS 'https://webapp-frontend.example.com' -H 'Origin: https://webapp-backend.example.com' -H 'Access-Control-Request-Method: POST'

Enter fullscreen mode Exit fullscreen mode

Of course I used curl for testing. To check if access-control-allow-origin works, you send a OPTIONS-request to check what methods are allowed by the application. The header 'Access-Control-Request-Method: POST' informs the application that I want to do a POST-request (I guess that’s not strictly necessary to test the allow-origin header).

Now to finally test it, I deactivated the access-control-allow-origin header, to see what will happen. Here’s the result:

> curl -v --request OPTIONS 'https://webapp-frontend.example.com' -H 'Origin: https://webapp-backend.example.com' -H 'Access-Control-Request-Method: POST'
* Trying 127.0.0.1:8000...
* Connected to 127.0.0.1 (127.0.0.1) port 8000
> OPTIONS /healthz HTTP/1.1
> Host: 127.0.0.1:8000
> User-Agent: curl/8.7.1
> Accept: */*
> Origin: https://webapp-backend.example.com
> Access-Control-Request-Method: POST
> 
* Request completely sent off
< HTTP/1.1 400 Bad Request
< date: Fri, 06 Sep 2024 11:44:27 GMT
< server: uvicorn
< vary: Origin
< access-control-allow-methods: GET, POST
< access-control-max-age: 600
< access-control-allow-headers: Accept, Accept-Language, Content-Language, Content-Type
< content-length: 22
< content-type: text/plain; charset=utf-8
< content-security-policy: base-uri 'self'; connect-src 'self'; script-src; script-src-attr; frame-src; object-src 'none'; img-src; style-src; font-src; manifest-src; media-src; default-src
< referrer-policy: no-referrer
< x-frame-options: DENY
< x-content-type-options: nosniff
< cross-origin-embedder-policy: require-corp
< cross-origin-opener-policy: same-origin
< cross-origin-resource-policy: same-origin
< 
* Connection #0 to host 127.0.0.1 left intact
Disallowed CORS origin

Enter fullscreen mode Exit fullscreen mode

The last line tells you that my request was denied. You can also see that there are three access-control headers in the response (access-control-allow-methods, access-control-max-age, access-control-allow-headers), but no access-control-allow-origin.

Now I activate the header in the application and re-run the curl command:

> curl -v --request OPTIONS 'https://webapp-frontend.example.com' -H 'Origin: https://webapp-backend.example.com' -H 'Access-Control-Request-Method: POST'
* Trying 127.0.0.1:8000...
* Connected to 127.0.0.1 (127.0.0.1) port 8000
> OPTIONS /healthz HTTP/1.1
> Host: 127.0.0.1:8000
> User-Agent: curl/8.7.1
> Accept: */
> Origin: https://webapp-backend.example.com
> Access-Control-Request-Method: POST
> 
* Request completely sent off
< HTTP/1.1 200 OK
< date: Fri, 06 Sep 2024 11:44:07 GMT
< server: uvicorn
< vary: Origin
< access-control-allow-methods: GET, POST
< access-control-max-age: 600
< access-control-allow-headers: Accept, Accept-Language, Content-Language, Content-Type
< access-control-allow-origin: https://webapp-backend.example.com
< content-length: 2
< content-type: text/plain; charset=utf-8
< content-security-policy: base-uri 'self'; connect-src 'self'; script-src; script-src-attr; frame-src; object-src 'none'; img-src; style-src; font-src; manifest-src; media-src; default-src
< referrer-policy: no-referrer
< x-frame-options: DENY
< x-content-type-options: nosniff
< cross-origin-embedder-policy: require-corp
< cross-origin-opener-policy: same-origin
< cross-origin-resource-policy: same-origin
< 
* Connection #0 to host 127.0.0.1 left intact
OK

Enter fullscreen mode Exit fullscreen mode

Now two things have changed:

  • I get back a OK-response indicating that my request ist allowed.
  • There’s now a header in the response: access-control-allow-origin: https://webapp-backend.example.com

And that’s it. With this simple method you can test on the command-line if your access-control-allow-origin works.

Top comments (0)