Exploitation of Mis-configured Cross-Origin Resource Sharing (CORS)

Before talking about Edmodo CORS Exploitation, have a look at
Same-Origin Policy(SOP) and Cross-Origin Resource Sharing(CORS) Concept.

Same-Origin Policy

The same-origin policy is an important concept in the web application security model.

Under the policy, a web browser permits scripts contained in a first web page to access data in a second web page, but only if both web pages have the same origin.

This policy prevents a malicious script on one page from obtaining access to sensitive data on another web page. It does not allow interactions between resources from different origins.

XMLHttpRequest(XHR) and the Fetch API follow the same-origin policy. 
you can fetch the data from a URL (i.e. GET method) using XHR & Fetch API. so the a web application using those APIs can only request a resources from the same origin.


Cross-Origin Request

If the script on your page is running from domain https://domain-a.com and would like to request a resource which is in another domain https://domain-b.com this is a Cross-Origin Request or Cross-Domain Request.


Understanding of CORS

Simple CORS Request :

is nothing but a normal HTTP request with some conditions.
In this scenario, client only making a GET, POST or HEAD request + Content-Type header limited to application/x-www-form-urlencoded, multipart/form-data, or text/plain. And the important header is Origin.

Request:

GET /fetching/some/resources HTTP/1.1
Host: api.example.com
User-Agent: …
Accept: …
Accept-Language: …
Referer: https://abc.example.com/home
Origin: https://www.example.com
Cookie: …

The Origin header tells the server that the client is originated from https://www.example.com
So the Server checks its same-origin policies And it determines whether to allow this request or deny it.

If the server allows the request, then it will respond with the requested resource and an Access-Control-Allow-Origin header in the response.
and If Access-Control-Allow-Origin is missing in the response or if it doesn’t match the request’s Origin, the browser will disallow the request.

[Access-Control-Allow-Credentials:true : The Cookie destined for the content on api.example.com, if api.example.com did not respond with an Access-Control-Allow-Credentials:true, the response would be ignored and not made available to web content.]

Response:

HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS, PATCH
Access-Control-Allow-Origin: https://www.example.com
Access-Control-Expose-Headers: Link, X-Total-Count
Access-Control-Max-Age: 1728000
Cache-Control: max-age=0, private, must-revalidate
Content-Type: application/json; charset=utf-8
Content-Length: 1009
Connection: keep-alive

[data…]

Pre-flight CORS Request :

If a request may have implications on user data, the browser sends a request before the original one by OPTIONS method to check whether it is safe to send the original request.

In this scenario, client making a DELETE request, The pre-flight request takes the form of an OPTIONS request with headers containing info about the DELETE request.

Request:

OPTIONS /users/account/id HTTP/1.1
Host: api.example.com
User-Agent: ...
Accept: ...
Accept-Language: ...
Access-Control-Request-Method: DELETE
Access-Control-Request-Headers: x-requested-with
Referer: https://www.example.com/settings
Origin: https://www.example.com
Connection: keep-alive

The server then check the request and if it allows, it responds withAccess-Control-Allow-Methods header) with the status code 200 OK.

Response:

HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: x-requested-with
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS, PATCH
Access-Control-Allow-Origin: https://www.example.com
Access-Control-Expose-Headers: Link, X-Total-Count
Access-Control-Max-Age: 1728000
Content-Type: text/plain
Content-Length: 1500
Connection: keep-alive

After this check, the browser will send the original DELETE request.


CORS for Attacker Point of View

Best cases for mis-configured CORS Exploitation

A. Misconfigured Wildcard Exploitation : The host domain api.example.comallows any Origin can access the resources.

Scenario 1 – Not Exploitable


Request

GET /fetching/some/resources HTTP/1.1
Host: api.example.com
Origin: https://www.example.com

— — —

Response

Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true


data...


Why it’s not Exploitable? –

There are some exception for above scenario 1, the CORS have some rule,
if the request headers contain a Cookie header, the request would fail if response of Access-Control-Allow-Origin header as wildcard(*).

Wildcard(*) is allow cross-origin XHR from any domain for fetching some public API (for ex: https://api.edmodo.com/profiles/1)
But in case, If Edmodo wants that the user first authenticate himself and then keep access to the data(using session cookies)
so, the XHR within this session (i.e. with credentials) is usually only expected to be same-domain or specified cross-origin domains.
and if the response back with ACAO: * and ACAC: true it will fail.

[developer perspective: If you want cross-origin XHR with credentials you need to explicitly specify the origins which are allowed to do this kind of sensitive access instead of just using a wildcard*]

Scenario 2 – Exploitable


Request

GET /fetching/some/resources HTTP/1.1
Host: api.example.com

Origin: null

— — —

Response

Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true


data...


Scenario 3 – Exploitable


Request

GET /fetching/some/resources HTTP/1.1
Host: api.example.com

Origin: https://attacker.com

— — —

Response

Access-Control-Allow-Origin: https://attacker.com
Access-Control-Allow-Credentials: true


data...


B. Pre-domain wildcard Exploitation: The host domain api.example.com trusted all origins that ended with host name example.comsuch as attackerexample.com

Scenario 4 – Exploitable


Request

GET /fetching/some/resources HTTP/1.1
Host: api.example.com

Origin: https://attackerexample.com

— — —

Response

Access-Control-Allow-Origin: https://attackerexample.com
Access-Control-Allow-Credentials: true


data...


For above Scenario 4, you need to purchase a domain attackerexample.comfor exploitation

C. Exploitation using XSS or Subdomain takeover: The host domain api.example.comtrusted only sub-domain origins such as sub.example.com

Scenario 5 – Exploitable


Request

GET /fetching/some/resources HTTP/1.1
Host: api.example.com
Origin: https://sub.example.com

— — —

Response

Access-Control-Allow-Origin: https://sub.example.com
Access-Control-Allow-Credentials: true


data...


For above Scenario 5, you have two options, Finding XSS on valid subdomain https://sub.example.com OR takeover the Subdomain.

using Subdomain takeover : If you successfully takeover the subdomain, upload your CORS poc there and fetch the user credentials.

using Cross Site Scripting(XSS): Once you find out XSS on subdomain, insert your CORS script in vulnerable point and fetch the user credentials.


Continue reading – Edmodo CORS Exploitation…

_______________

References :


Thanks for Reading… 😊

Happy Hunting…!!!
👍 ✌️