In this article, we will explain what a CORS policy is and what CORS is in general, as well as how it is useful for developers.

image
For modern web applications, loading resources from multiple domains is a common practice. These resources are accessed using CORS technology. For example, if you need to get information about a user on your website " www.mysite.com " from a server located at "api.website.com", you must send a request to the server and receive a response in the form of JSON data.

What is CORS ?
CORS (Cross-Origin Resource Sharing) is a mechanism that gives permissions to download resources from one source to another, while maintaining the integrity of the site and protecting it from unauthorized access . Modern browsers use this to determine which cross-site requests are safe.

For security purposes, browsers restrict access from scripts to other resources that exist outside their domain using the Same-Origin Policy (Same-Origin Policy). This policy protects against identity theft from other web servers or Cross-Site Request Forgery (CSRF ) attacks.

In this case, one source, the attacker's site, is trying to access a resource from the source, the online banking site. Same-Origin Policy blocks a cybercriminal from accessing your bank details.

However, domain restriction rules restrict specialists from accessing resources from different sources. Therefore, the CORS HTTP protocol was developed to tell the browser that limited resources on a web page can be requested from other domains.

For example, here is a possible scenario for requesting information from an external source such as an API (a common practice for client-side JavaScript code):

The resource origin makes a preflight request to an external web server using CORS headers;
The external web server then checks this pre-request to ensure scripts are allowed to make the request;
Once validated, the external web server responds with its own set of HTTP headers that define valid request methods, origins, and custom headers. The server response may also include information about whether it is acceptable to pass credentials such as authentication headers.
Why do I need CORS ?
If you want to use resources from a server other than your own, you will need to use CORS.

Some examples of what you can do with CORS include:

Using web fonts or style sheets (Google Fonts or Typekit) from a remote domain;
Specifying the location of users on the map through the Google Map API: https://maps.googleapis.com/maps/api/js ;
Displaying tweets from the Twitter
API handle: https://api.twitter.com/xxx/tweets/xxxxx ;
Use of Headless CMS for content management;
Access to any API hosted on another domain or subdomain.
How does CORS work?
The CORS job starts when a script from one origin sends a request to another origin. All of this is controlled by a pre-request that exchanges HTTP request headers and response headers called "CORS headers".

Let's take a closer look at how preflight requests work.

preliminary request

A Preflight request is an additional HTTP request using the "OPTIONS" method. The browser does this for every insecure request that changes data, such as POST, PUT, or DELETE requests.

The preflight request is standard behavior for modern web browsers. The expected response from the application is a response that contains CORS headers with the correct instructions.

Pre-request example:

Here we see some specific HTTP headers. These are some of the most common CORS headers used in browser requests and server responses:

Access-Control-Allow-Origin
Access-Control-Allow-Methods
Access-Control-Allow-Headers
Let's take a closer look at how these CORS headers work.

Access-Control-Allow-Origin
Imagine the following scenario: I want to allow an application hosted at https:// mywebsite. com , access to the resource.

In this case, I need to specify the following:

Access-Control-Allow-Origin: https://mywebsite.com

Also, adding a custom Access-Control-Allow-Origin header in object stores like AWS S3 or Google Storage will optimize throughput, optimize resource usage, and speed up data retrieval.

Access-Control-Allow-Origin can also be used if another site completely copies yours, which negatively affects your site's SEO. This way, your website content will not be displayed on the mirror site. But you can also file a DMCA Takedown Notice to remove your content from another site, as an attacker can bypass the Access-Control-Allow-Origin policy using a proxy.

Security issues with Access-Control-Allow-Origin
It is quite common to find applications using this notation for Access-Control-Allow-Origin:


The "*" character tells the browser to allow access to the resource from any origin, effectively disabling the Same-Origin Policy . This means that the browser will not filter sources. Any code on any site can make a request to a resource (including malicious domains).

Also, the "*" character is widely used by hackers, especially for web skimmers. AJAX requests are sent from checkout pages on hacked sites to malicious servers that relay stolen payment details.

For example, this JavaScript skimmer uses a cross-origin request with appropriate CORS headers to send stolen data to a third-party server.


Part of the JavaScript credit card skimmer exfiltration.

Here is an example of the CORS headers used for the web skimmer exfiltration URL:


Essentially, hackers use these "*" CORS headers on their servers to get data from any hacked websites. So if you also use CORS headers with "*" for any server responses, you make it easier for attackers to use your sites to steal data.

Access-Control-Allow-Methods
When developing a RESTful API, most endpoints will accept GET, POST, PUT, PATCH, and DELETE methods.

With the Access-Control-Allow-Methods header , you can specify exactly which HTTP methods your application should expose to external sources. This can help reduce the risk of any unwanted activity in your environment.


This header reserves the use of POST, PUT, PATCH, and any type of HTTP method that is used to modify application content in your domain. This allows external applications to use GET requests to read-only resources.

Access-Control-Allow-Headers
The purpose of the Access-Control-Allow-Headers header is to allow custom headers. For example, an application that uses "X-My-Header" must respond to a preflight request with this header in its allow list.


If the header is not allowed, the developer console will display the following error:

X header field authorization is not allowed by Access-Control-Allow-Headers in preflight response.

How to enable CORS on my server?
You can easily change the CORS settings on any Apache server by modifying the ".htaccess" file.

Open a file manager or sFTP;
Navigate to your website directory;
Open your ".htaccess" file or create a new one;
Include CORS directives in the content of the file.

For NGINX users, CORS is enabled using the main Headers module.


How to enable CORS on WordPress
1. Set up the CORS header function

Add the following code to the "functions.php" file.

This is where you check to see if your environment is in production mode. If so, then the "$origin_url" value will change to your actual domain.

2. Enable the CORS feature

Add the following action "rest_api_init". It is added directly below the "initCors" function we just created.

3. Allow support for multiple origins

If you want to add support for multiple origins, create an array of allowed origins.

How to avoid using CORS?
Working with CORS can complicate your setup. You can always bypass CORS by adding a proxy between your web server and the API that makes it appear that requests are coming and going from the same domain. However, this should only be used as a temporary workaround during development.

Website Security with CORS
CORS is a way to improve client-side security for your web application, but it should not be used as the only layer of security.

It's worth noting that CORS does not protect against cross-site scripting (XSS) , and if configured incorrectly, it can leave your site vulnerable to attacks. It's easy for an attacker to directly forge a request from any trusted source, so you need to enforce server-side security rules.

Apply the following security measures to your site:

do not use the wildcard "*" to prevent every script you load from being associated with a resource;
check all access control request headers against the appropriate access lists;
try a simple but safe string comparison against an array of trusted values ​​to mitigate the risk;
use as many levels of protection as possible;
regularly apply updates with fixes for software vulnerabilities;
set up access control rules;
use a website firewall.