SOP and CORS Concept | Understanding of CORS | CORS for attacker point of view | Best cases for mis-configured CORS Exploitation
Before talking about Edmodo CORS Exploitation, let's take a look at Same-Origin Policy (SOP) and Cross-Origin Resource Sharing (CORS) concept.
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.
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.
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…]
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 with Access-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.
A. Misconfigured Wildcard Exploitation :
The host domain api.example.com
allows 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…]
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.com
such 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.com
for exploitation.
C. Exploitation using XSS or Subdomain takeover:
The host domain api.example.com
trusted 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 Cross Site Scripting(XSS):
Once you find out XSS on subdomain, insert your CORS script in vulnerable point and fetch the user credentials.
- Using Subdomain Takeover :
If you successfully takeover the subdomain, upload your CORS poc there and fetch the user credentials.
- https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
- http://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
Happy Hunting…!!! 🔱
Next Post 🔰 : Edmodo Users Private Information Disclosure : CORS Exploitation