DEV Community

Warren Parad for Authress Engineering Blog

Posted on • Edited on

I got a CORS error, now what?

I got a CORS error, of course you did, but there isn't just one kind of CORS error, there are many. To solve a CORS error, you need to start debugging. And that begins with understanding a bit about the process.

CORS or Cross-Origin Resource Sharing, means that your website is running on a different domain than the API you are calling:

Seeing the error means that the response from the API is incorrect. If you don't control the API that is returning data, you can't fix the problem yourself, end of story (Note: there is one rare case where you can, but I'm not going to go into that at the moment.)

I'll say that again, if you don't control the API, then you cannot fix this problem. And frequently means that you are trying to do something that the API owner explicitly wants to protect against. (although this isn't the same as security, and any API provider that says this doesn't know the first thing about security)

Further, to investigate any and all CORS related issues, you MUST use a terminal, you cannot fix CORS errors by using a browser. The reason is when a CORS error appears, your browser immediately discards the error data to prevent it from being used maliciously. Terminal investigation is done by navigating to the Network Inspector tab and right-click the failing request, and copy it to cURL:

How to copy curl command

Then run the cURL in your terminal of choice. This terminal must NOT be windows CMD. If you don't have another terminal, there are options, but I don't recommend them. (For instance you can try the Online CORS tester, but because this isn't the same request as the one your browser sent, you likely won't get a conclusive answer.)

The CORS flow - Preflight failures

There are two different requests that can fail:

  • OPTIONS - also known as preflight
  • METHOD - GET/POST/etc.. the real request

The preflight is optional and your browser may or may not send it. It is an OPTIONS Method request, it needs explicit configuration. If the preflight fails, it is usually due to either a misconfiguration of your infrastructure, and so it is possible that you did not correctly configure it correctly to handle CORS. OR You did configure it correctly, but your code isn't designed to handle an OPTIONS request. Here are some things that are important about an OPTIONS request:

  • There is no body - OPTIONS requests do not contain a body, end of story, so if your code depends on it, that's your bug
  • There is no Authorization header - The headers are completely different.
  • You must return access-control-allow-headers, access-control-allow-methods, and access-control-allow-origin

It works when I use postman

That's for two reasons:

  1. It isn't sending the CORS request. A CORS request is something only sent by the browser, I don't care if it works in postman, insomnia, or in curl, I care WHAT THE RESPONSE is. While it will work in these tools, the response to the preflight is what matters. If your method isn't OPTIONS, you are testing wrong.
  2. I AM DOING OPTIONS, but it still works. That's because your code that you are running can handle a vanilla request but there is something being included in the preflight that fails. The first step is always reproduction, until you can get postman to reproduce the same error, that is 100% what you need to be focused on doing. Spending any time "trying to fix CORS" before reproducing the bug, is the definition of insanity. Trying the same thing and expecting different results.

I still get a CORS error with a 4XX or 5XX. CORS errors don't produce 4XX or 5XX. If you get a 4XX or 5XX, that is what is causing the CORS error. Forget CORS and first fix your code. The best way to debug this is get the actual request and actual error from your production logging solution. With Lambda in AWS this is CloudWatch. If it isn't being logged, improved your logging until you get the error. Solutions don't just return 5XX themselves, you are doing something wrong.

Cross-origin request blocked: Same origin policy prevents
reading of remote resource at
"https://apiid.execute-api.eu-west-1.amazonaws.com"
(reason: failure in the CORS preflight response).
Enter fullscreen mode Exit fullscreen mode

This is almost a working CORS configuration, but you likely have, the access-control-allow-origin header, value does not match your UI.

The actual request

After a successful preflight response, the browser will make the second request to the service. When this due to a CORS error it is because the response back does not contain the access-control-allow-origin header. Yes ALSO THIS RESPONSE requires the access-control-allow-origin.

If the code "looks right", but the response to the website is a 4XX or 5XX, then it is likely your "happy-path" works correctly, but the error-path does not. My recommendation is to add access-control-allow-origin: * to all responses, including the error ones, so that the real response can be passed to the browser.

It just started failing today, what changed

Your browser probably. Some browser delivery too much or not enough data to validate requests. Browsers are changing all the time and CDNs/Cloud Providers try to keep up. The almost always do in a backwards compatible way. Don't assume the cloud provider changed and broke your site. Go back and revalidate the error and what is sent to your service. If you are getting a CORS error now, your web app delivering content probably wasn't prepared to handle the request correctly.

For instance browsers make have decided to start relying on new tech, such as sec-fetch-site, and no longer send the Origin header. Is this a problem for your CORS handler? If yes, you'll need a workaround. Time to start in on that. This is just another reason you don't want to write this yourself, use a CDN, use serverless, and most of all, find a SaaS to solve the problem, be it your cloud or something else. Don't run a website proxy service on a virtual machine, it's going to be a bad time.

Wait, tell me about...

When do I use the wildcard *

I've suggested multiple times in this article to use the *. This is usually the correct solution, and you actually don't have to worry about CORS at all. Just set this as *, pat yourself on the back, and move on.

If you have any dependence on Cookies, which is usually wrong, stop doing that. If you really really need them, then you'll need start thinking about what the CORS response should be. But in reality you are better off stop using cookies, then you won't have to worry about any nasty security vulnerability, and all your CORS problems go away.

But I really really need cookies

The only time cookies are going to be valuable is you want to track your users. This only makes sense to two situations:

  • You are a malicious website advertiser
  • You are building Auth as a service

In the first case, I'm sorry this post isn't for you, I'm not going to help malicious advertisers. And in the second case, we wrote Authress to do this, so you don't have to. And cookies work out of the box there :)


Come join our Community and discuss this and other security related topics!


Join the community

Top comments (0)