Using OWASP ZAP to test for CORS origin reflection exploits
Cross-Origin Resource Sharing (CORS) protects a user from having sensitive information leaked from one site to another. If the browser allowed any cross-domain XHR requests, sites would be able to steal information from other sites that you are logged into by making authenticated requests to them via JavaScript (the target site’s cookies will be sent with the request). But CORS can be easily misconfigured and result in vulnerabilities in your site, one particular misconfiguration is CORS origin reflection, where the Origin
request header is processed through a whitelist (or regular expression) on the server and if allowed, is returned in an Access-Control-Allow-Origin:
response header. Poor regex can result in allowing unintended domains through.
In this post I’ll walk you through using OWASP ZAP to manually test a list of domain names passed as origins to a webserver, and evaluating whether they are reflected in the allowed CORS domains.
Let’s imagine that a website has been configured to allow CORS requests from https://target.com
or any subdomain of target.com
. When a request is made to the server like
GET https://auth.target.com/token
Host: https://auth.target.com
Origin: https://app.target.com
Then the webserver may compare the Origin
header to a regex like https:\/\/(.*)target.com
. If the origin matches the regex then the server returns a CORS header like
Access-Control-Allow-Origin: https://app.target.com
Echoing the same origin back to the browser. But this regex is too permissive. An attacker could register https://eviltarget.com
and this would also pass the server check. We’re going to test for overly permissive server checks using OWASP ZAP, a free vulnerability scanner similar to BurpSuite.
Steps to test for CORS origin reflection
Assuming you’ve configured a browser to proxy requests through OWASP ZAP, fire up ZAP, launch your browser and make a request to the target site.
In OWASP ZAP, find the request you want to test, either within the Site tree or in the History tab, right click on it and select Attack > Fuzz…
This will open the Fuzzer dialog. The first thing we want to do is provide a list of origin payloads and where to inject them.
On Fuzz Locations tab, highlight the Origin header where you want to inject different origin payloads.
On the right hand pane, under Fuzz Locations, click Add.
On the Payloads dialog, click Add.
On the Add Payload dialog, select the Type: String and enter the origins you want to test.
Now we want to add a message processor to flag when we see an origin reflected in the CORS header.
Click the Message Processors tab and click Add.
Select Type: Tag Creator and choose the Extract option.
In the Regex, enter: Access-Control-Allow-Origin:(.*)
Finally, click Start Fuzzer. You should see the results in the State column of the Fuzzer tab in the bottom panel.