Cross-Origin Resource Sharing (CORS)
What is CORS?
Web pages, say like http://example.com/page, can always request resources from another web page as long as it comes from the same origin (this includes protocol, domain, and port). This same origin policy helps prevent malicious behavior since data circulates only from within the domain.
But what if the resources you need are only available elsewhere? This is where CORS come into play. It allows you to access resources or to navigate to another server. This is helpful especially when loading images, scripts, stylesheets, etc. CORS requests are done by using standard HTTP methods such as GET
, PATCH
, POST
, PUT
, and DELETE
and are implemented using HTTP headers.
HTTP Request Headers:
Origin
Access-Control-Request-Method
Access-Control-Request-Headers
HTTP Response Headers:
Access-Control-Allow-Origin
Access-Control-Allow-Credentials
Access-Control-Expose-Headers
Access-Control-Max-Age
Access-Control-Allow-Methods
Access-Control-Allow-Headers
Access-Control-Allow-Origin
allows servers to specify how their resources are shared externally. Many times, this header will be set to *
pertaining to any external domain. It could be a list of domains or it could even be set to null
.
Most servers only allow GET
requests as to avoid any intention of maliciously editing or deleting assets. However, such requests are not automatically dropped by the server. It first undergoes a preflight test in order to determine what methods are allowed.
Pre-flight Test
It first sends an
OPTIONS
request:The server responds:
After the pre-flight test, the original request is then handled.
Deleting a resource:
The server responds:
Since the DELETE
method was allowed after checking during the pre-flight test, the resource was successfully deleted. Other headers automatically added by the browser are omitted from the example above.
Common Misconfigurations
Access-Control-Allow-Credentials
is set totrue
:Credentials are often stored in cookies and cookies are used to maintain our sessions or what the browser uses to indicate that we are currently logged in. Its value is mostly unique to our own and this header enables credential transmission which is bad new especially for websites susceptible to [Cross-Site Scripting (XSS)](https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)).
This would only be exploitable if
Access-Control-Allow-Origin
is not set to a wildcard (*
) even if the a wildcard was used to cover a website's subdomains (e.g.*.example.com
).Exposing your website to everyone and used along with this header the console would return
Cannot use wildcard in Access-Control-Allow-Origin when credentials flag is true.
This could be a work around but this is still bad practice.Access-Control-Allow-Origin: null
Hostile documents could be crafted and sent with a
Origin: null
header and it would be accepted since serialization of theOrigin
of files are defined to be null.This should not be used.
Don't give unneeded methods in
Access-Control-Allow-Method
DELETE
,PATCH
,POST
, andPUT
could be used to alter or remove a site's assets/resources and even trigger further unwanted actions.Giving access to everyone --
Access-Control-Allow-Origin: *
Perhaps adding specific websites to a white list might be advisable if resources contain somewhat sensitive content.
Or perhaps limiting accessible subdomains and endpoints would prove to be more secure but this would require different configurations.