Before we can answer that, we need a little background. The Same-Origin Policy (SOP) restricted information sharing between applications and allowed sharing only within the domain the application was hosted on. This was a precaution to protect systems from giving up confidential information. But, with the growing usage of web-applications and microservices, there is a need to pass information from one subdomain to another, or between different domains for practicality purposes. This need might be for rendering purposes or for crucial functionality such as passing access tokens and session identifiers to another application.With SOP in place, in order to allow cross-domain communication, developers had to use different techniques to bypass SOP and pass sensitive information. The ‘by-passing’ happened too much to a point that it became a security issue. So, in order to enable information sharing without compromising the security posture of applications, the Cross-Origin Resource Sharing (CORS) was introduced in HTML5.
Cross-Origin Resource Sharing (CORS) is a mechanism that enables web browsers to perform cross-domain requests using the XMLHttpRequest API in a controlled manner. These cross-origin requests have an Origin header, that identifies the domain initiating the request. It defines the protocol to use between a web browser and a server to determine whether a cross-origin request is allowed.
When this protocol has been incorrectly configured, it makes it possible for a domain controlled by a malicious party to send requests to your domain. I (hopefully) don't have to tell you why that's a huge problem. As a security analyst or an engineer, it is important for you to understand how misconfigured CORS headers can be exploited. The business implications of this can be anywhere from stealing data to compromising your entire application. Understanding the risks will enable to better remediate it before a catastrophe.Learn more: How AppSec testing can make your app development easier than ever
There are a number of HTTP headers related to CORS, but the following three response headers are the most important for security:
When it comes to CORS misconfigurations, one of the most common examples is incorrectly using wildcards such as (*) under which domains are allowed to request resources. This is usually set as default, which means any domain can access resources on this site. For example, consider the below request:
GET /api/userinfo.phpHost: www.victim.comOrigin: www.victim.com
When you send the above request, you get a response with the Access-Control-Allow-Origin header setting. See the below response code.
HTTP/1.0 200 OKAccess-Control-Allow-Origin: *Access-Control-Allow-Credentials: true
In this example case, the header is configured with a wildcard(*). It means any domain can access the resources.
While testing one of our client’s web application, we noticed this exact misconfiguration. We were able to exploit it to fetch user information like Name, User-ID, Email-ID and were able to send this information to an external server. In the below image, we modified the REQUEST Origin from victim domain to attacker domain.
Image: Tampered origin URL under REQUEST
Below is the response we received. The wildcard is shown in the origin header response with Access-Control-Allow-Origin: *, which means victim domain allows access to resources from all sites. Testing.aaa.com site in our attack case.
Image: Response from the REQUEST
Since the site shares information from any site, we went further and exploited it using our own domain. We created our domain called https://testing.aaa.com, and embed it with exploit code to steal the confidential information form the vulnerable application. When victims open https://testing.aaa.com in the browser, it retrieves the sensitive information and sends to the attacker’s server. See below image for the kind of information you can gather with this attack.
Image: Application sends sensitive information to attackers
Another common way CORS misconfigurations are exploited is by allowing information sharing with domain names that are partly validated. For Example, consider the below REQUEST
GET /api/userinfo.phpHost: provider.comOrigin: requester.com
And the response to the above request would be
HTTP/1.0 200 OKAccess-Control-Allow-Origin: requester.comAccess-Control-Allow-Credentials: true
Consider if a developer had configured CORS to validate the “Origin header” URL, with the white listed domain as just “requester.com”. Now, when the attacker crafts the REQUEST as below:
GET /api/userinfo.phpHost: example.comConnection: closeOrigin: attackerrequester.com
The unassuming server would respond with
HTTP/1.0 200 OKAccess-Control-Allow-Origin: attackerrequester.comAccess-Control-Allow-Credentials: true
The reason this happens is a possible backend badly configured validation such as this:
if ($_SERVER['HTTP_HOST'] == '*requester.com') {//Access dataelse{ // unauthorized access}}
We came across this in one of our client’s application. The host domain “provider.com” trusted all origins that ended with host name “requester.com” such as “attackerrequester.com”. So, we tampered the origin header to attackerrequester.com and proceeded with the request.
Image: Tampered origin URL under REQUEST
In the below response, the same origin is reflected in the response Access-control-Allow-Origin header, which means provider.com domain allows sharing resources to domains which end with requester.com domain.
Image: Response from the REQUEST
This can be exploited the same way we did for the first CORS misconfiguration. We can create a new domain with the name consisting of the whitelisted domain name. Then, embed that malicious site with exploits that will fetch sensitive information from the victim’s site.
One defense mechanism developers use to exploitation of CORS is to whitelist domains that frequently requests access for information. However, this isn’t entirely secure, because if even one of the subdomains of the whitelisted domain is vulnerable to other exploits such as XSS, it can enable CORS exploitation.
Let us consider an example, the following code shows the configuration that allows subdomains of requester.com to access resources of provider.com.
if ($_SERVER['HTTP_HOST'] == '*.requester.com') {//Access dataelse{ // unauthorized access}}
Assuming that a user has access to sub.requester.com but not requester.com, and assuming that sub.requster.com is vulnerable to XSS. The user can exploit provider.com by using cross-site scripting attack method.
As a proof of concept, we hosted two applications on the same domain. The provider CORS application is hosted on testingcors.com and another application is hosted on pavan.testingcors.com which is vulnerable to cross-site scripting.
Image: Shows that pavan.testingcors.com is vulberable to XSS
Using this vulnerable XSS subdomain, we are able to fetch sensitive information from testingcors.com. We injected the malicious javascript payload in the “Name” parameter. When the page loads, the script gets executed and fetches sensitive information from the testingcors.com.
Image: Shows the retrieved information from the XSS exploit
Cross-Origin Resource Sharing is an OWASP TOP 10 Security Misconfiguration vulnerability. In the process of enabling information sharing between sites, people tend to overlook the significance of CORS misconfiguration. As developers or security experts, it’s very important that you are aware of this vulnerability and how it can be exploited.