Using OWASP ZAP to test for CORS origin reflection exploits

posted on 15 June 2020 in infosec

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.

OWASP ZAP Fuzz Dialog

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.

OWASP ZAP Add Fuzz Locations Dialog

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:(.*)

OWASP ZAP Fuzzer Tag Creator

Finally, click Start Fuzzer. You should see the results in the State column of the Fuzzer tab in the bottom panel.

OWASP ZAP Fuzzer Results