In recent web application assessments, I’ve found a number of client applications that have cross-origin resource sharing (CORS) vulnerabilities—which I flagged as Critical because they left the application wide open to a range of potentially very damaging attacks.
While CORS security issues are well described (they’re associated with vulnerability categories A5-Security misconfiguration and A8-Cross-site forgery in the OWASP Top Ten), many developers are still not aware of how to implement CORS securely, or the importance of doing so. This post offers basic guidance on how to eliminate major risk associated with CORS misconfigurations.
What is Cross-Origin Resource Sharing?
Cross-origin resource sharing is an HTML 5 mechanism that augments and to some extent relaxes the same-origin policy to support and simplify the sharing of resources across domain boundaries. The CORS specification defines a set of headers that allow the server and browser to determine which requests for cross-domain resources (images, stylesheets, scripts, data, etc.) are allowed and which are not.
In a nutshell, CORS is a security policy framework standard that browser developers jointly support. At its core, it’s a browser side protection framework.
Cross-origin resource sharing is very important in today’s world of complex, enterprise applications and all browsers support it. A single company having multiple applications across multiple domains that interact with each other (typically via CORS) is now the norm. In particular, CORS is now typically used for cross-domain AJAX requests.
Key CORS headers
A number of HTTP headers relate to CORS, but two response headers are most important for security:
- Access-Control-Allow-Origin specifies which domains can access a site’s resources. For example, if ABC Corp. has domains ABC.com and XYZ.com, then its developers can use this header to securely grant XYZ.com access to ABC.com’s resources.
- Access-Control-Allow-Methods specifies which HTTP request methods (GET, PUT, DELETE, etc.) can be used to access resources. This header lets developers further enhance security by specifying what methods are valid when XYZ accesses ABC’s resources.
The Key CORS Security Issue: Failure to Validate
The most common and problematic security issue when implementing CORS is the failure to validate/whitelist requestors. Too often developers set the value for Access-Control-Allow-Origin to ‘*’. Unfortunately, this is the default. This allows any domain on the web to access that site’s resources.
How to Avoid CORS Vulnerabilities
To implement CORS securely, you need to associate a validation list with Access-Control-Allow-Origin that identifies which specific domains (e.g., your company’s other domains) can access resources. Then your application can validate against this list when a domain requests access.
Should You Ever Set Access-Control-Allow-Origin to * ?
The one and only time when it would be appropriate to set Access-Control-Allow-Origin to ‘*’ is for sites that serve only public content—otherwise, don’t do it. Even if your site is only accessible on an internal network, ‘*’ is unsafe. Why? If you’re accessing your site in one browser window and you’re interacting with an external site in another window in the same browser, a hacker can coopt the latter site to request any method whatsoever against resources or data on your internal site: GET, DELETE, you name it.
What About Access-Control-Allow-Methods?
Similarly, with Access-Control-Allow-Methods you should specify exactly what methods are valid for approved domains to use. Some may only need to view resources, while others need to read and update them, and so on.
For example, your organization might have both an eCommerce site and a blogging site. You might want to use Access-Control-Allow-Methods in association with Access-Control-Allow-Origin to allow bloggers to post that they just bought a particular product, which could involve READ access to data from your eCommerce site. But if you fail to implement CORS securely, hackers could, for instance, remove an item for sale on your eCommerce site, or change its price and then buy it at the lower price.
It is quite easy for a hacker to setup a traffic viewer and observe what requests are passing back and forth from your site and what the responses are. From this, they can determine whether your site is vulnerable to a CORS-based attack.
Therefore, again, you should be validating each and every domain that is requesting your site’s resources, as well as the methods other domains can use if their requests for access are valid.
Achieving Robust CORS Security
Validating origins and methods is just the beginning of robust, flexible CORS security. For example, in addition, you could require credentials from requestors by setting up the header Access-Control-Allow-Credentials.
As more and more web applications rely on cross-domain resource exchange, and more and more programming language frameworks (e.g., Java, Spring, RESTful services) support CORS in various ways, it’s essential—at a minimum—that you implement CORS as described above to help prevent data loss, data exfiltration and/or data availability concerns.
Partner with Application Security Experts
To identify security vulnerabilities in critical applications that put your data and operations at risk, including how best to prioritize and mitigate them, contact Pivot Point Security.
For More Information on Cross-Origin Resource Sharing:
- OWASP guidance on testing your CORS mechanism
- OWASP guidance on using the Origin header in CORS
- A discussion of the security impact of a misconfigured CORS implementation (with code examples)