What is Cross-Origin Resource Sharing (CORS)?

Introduction

Cross-Origin Resource Sharing (CORS) was first implemented in 2006 by the World Wide Web Consortium (W3C). It was created so that resource sharing between two or more different origins is as secure as possible. This mechanism is important because by default web browsers prevent scripts on one domain from making requests to another. CORS provides a way for the server to specify which origins are allowed to make requests, and for the browser to enforce these restrictions.

What does CORS do?

Note that CORS uses the word origin in its name. Origin stands for a whole website URL, without the potential query string. In other words, schema (or protocol) + domain + port number. An example of an origin could be https://www.example.com:443. You don’t usually see the port number, but it is good to know that CORS cares about it.

In this article, we might use different wording like domain or site, but the consensus is the same where it symbolises one website. 

But what exactly does it do? I think a real-life analogy example is the best way to introduce a new concept. We can think of CORS like the bouncer in a club. The bouncer checks everyone’s ID to see if they are allowed entrance. You can think of that as a security for both the club and the authorised guests. The club is the resource sharer and the people wanting entrance as the resource requesters. In both scenarios, you can see that CORS is in the middle as the security and the IDs (the guest list) as the web server is saying who can or can’t fetch the resources (or beer).

Why is CORS so important?

As mentioned earlier, CORS is implemented by default in every major browser today. This is important to have as a safeguard against malicious activity that might come from another domain.

Let’s say CORS doesn’t exist, and your site and/or web server has a vulnerability which could be exploited, we set ourselves up for potential real damage. We can take a cross-site scripting (XSS) attack as an example. This means we get a request which seems to come from a trusted third-party domain. This request apparently wants to get some information about a user in our system. We trust them, so we say “Sure, go ahead”. But what happens is that this trusted request comes with some inlined JavaScript code which changes the user’s password, as that is our vulnerability.

Voila! Our user account has been breached. In the best-case scenario, this is just a normal user. Worst case scenario, this is an administrator account and our whole system is potentially hacked.

Having a say in who and what another website can and can’t do in the first place is exactly what we use CORS for.

But how do I fix a CORS error?

In most cases you will see something along the lines of this error:

Access to fetch at ‘https://sharer.oskibri.site/api/’ from origin ‘https://requester.oskibri.site’ has been blocked by CORS policy: No ‘Access-Control-Allow-Origin’ header is present on the requested resource. If an opaque response serves your needs, set the request’s mode to ‘no-cors’ to fetch the resource with CORS disabled.

In this example, we have two origins. We have the one who owns the wanted resource at HTTPS://sharer.oskibri.site/api, and we have you or the origin that requests the resource at https://requester.oskibri.site.

So this error simply means that the website which shares the resource you need hasn’t allowed you (or anyone) to fetch that resource. In this example the fix is simple: Make the origin that owns or wants to share the resource to allow cross-origin sharing. That is done by telling the web server of the sharer to respond with a header which either allows every origin or a specific origin.

There are different ways to set such a header, like in the code where the resource exists. But the simplest method is to set it in your .htaccess file, in the site’s webroot. The line of code to add to .htaccess is:

Header always set Access-Control-Allow-Origin: "https://requester.oskibri.site"

Here you change out the origin (https://requester.oskibri.site) with your own site’s URL. Or you can change it out with a wildcard (*) to allow everyone to fetch any resource from your origin:

Header always set Access-Control-Allow-Origin: "*"

Of course, in this example, we have control over both websites, but in most cases, you won’t have control over the origin or the webserver where the resource lives. In that case, you need to contact the owner of that origin and tell them to add your origin to their Access-Control-Allow-Origin header value.

How to debug CORS errors

When it comes to CORS, the web browser’s development tools are your friend. In the image above where I saw the error, I used Chrome’s Dev Tools and looked in the console. It’s usually a fault with the response header from the sharer. So the first thing to inspect is the site’s web server to see if the headers are correctly set. You can also use a tool like cURL to inspect the response headers, if using the terminal is more your style. 

If everything seems correct with the response headers sent by the resource, it might be that some server configuration is wrong. If that is the case you will also need to contact the resource owner or their hosting. 

Lastly, if there is nothing wrong in any of the steps above then you might have some wrongly configured code. Double-checking your code is always a good thing to do at this step.

Finally, it might of course be something outside anyone’s control like a network fault. Here, patience is key.