CORS: Attack scenarios

I was preparing myself for the Hacktivity conference in Budapest, where I talked about the security of the Cross-Origin Resource Sharing (CORS). As part of the preparation I summarised my thoughts in a couple of blog posts. This is one of them.

As a follow up of my previous post, I would like to continue with the short analysis of the threats and attack scenarios which could exploit CORS.

There are a few things to consider here. First, that CORS is not broken. It is just a feature that can support other already existing attacks to exploit other vulnerabilities. From penetration tester point of view CORS is rather a tool, then a vulnerability. Second, the most important property in CORS is that it allows you some kind of pass through the same-origin policy with a handful of limitations.

First let’s see the possible attacks from three different perspectives:

  • Goal of the attack
  • Target’s location
  • Type of attack

1) Goal of the attack

To start off with, it is worth to understand what kind of goals can an attacker have in mind.

Exploit Cross-Site Request Forgery

The most critical problem that an attacker can exploit with CORS is the Cross-Site Request Forgery(CSRF). The main reason for that is that, with CORS the attacker can send a complex set of requests to the server even with session cookies. For instance before CORS it was a bit difficult to order a product as the CSRF attack if the order process was multistage. In that case the attacker had to submit multiple forms to send the correct requests, however, with CORS it is possible to implement the whole attack in JavaScript and when the user loads the attacker’s malicious website the JavaScript can immediately start to send requests to the target.

Another important aspect is the file upload CSRF. I have already written about that here, so I won’t go into details, however, the point is that before CORS it was not possible to upload files through CSRF because of the ‘filename’ attribute in the request. But now it is possible because JavaScript can be used to build the request.

Interact with the internal network

If the user loads the attacker’s website in the company network, that essentially means that the attacker can execute code in the internal network. Of course some pretty strong limitations apply, which I will describe in the ‘Limitations’ part. So in this case the attacker can use CORS to try to explore the network, find well known service, try to do simple scanning etc.., or simply attack a known internal service which he has no access to.

2) Target’s location

Another important aspect of attacks is the location of the target. Here when we say ‘target’, then the target service is meant, so not the user who loads the malicious content but the service, which the hacker wants to attack through CORS.

Attacking services on the Internet

This is pretty straightforward. The attacker wants to attack a service which runs publicly on the Internet, however, he wants to access some restricted content, or he wants to do it in the name of somebody else. He can setup a malicious page, trick the user to load it and when he does, the page can interact with the target service from the user’s browser. An (imaginary) example would be the following: let’s assume that Facebook has a CSRF vulnerability in the share functionality. When the innocent user opens the malicious website, the JavaScript on it send a request to Facebook to share something (which complies with the attacker’s goal) on the user’s wall. Because of CORS the JavaScript can do that and with the ‘withcredentials’ XmlHttpRequest attribute the script can access the authenticated session of the user.

Attacking internal services

In the second part the attacker uses CORS and the user’s browser as a pivot point to get access to the internal (company) network. When the user loads the attacker’s malicious page the JavaScript will be able to access services, which are not accessible for the attacker from the Internet.

3) Direct vs Indirect

Direct attack against services

I wanted to mention this case, because it might seem trivial, but still there are many people doing such mistakes because they misunderstand CORS. So the problem is that some people considers CORS as some kind of authorization mechanism. This is coming from the fact that if you send an XmlHttpRequest and the server rejects your CORS the response data will be not available for the JavaScript. What they forget is that the data is still sent to the client and the browser decides based on the response’s Allow-Origin-* headers whether to allow it to the JavaScript or not. Unfortunately this solutions fails terribly when the client happens to be a script or a netcat running in the terminal. So when I write direct attack, I mean that the attacker connects directly to the service and not through the browser of some other user.

Indirect attacks

The indirect attacks are the traditional client side attacks, when the malicious code is injected in a website, that has to be loaded by the user. When the page is loaded the malicious code attacks the target service from the user’s client.

4) Limitations

As mentioned before there are pretty strong limitations when using CORS.

Write only requests

Often when the service is well configured or not configured at all, the response will not be readable for the JavaScript. For instance if the HTTP response has no Access-Control-Allow-Origin header, then , although all data were sent to the client, the JavaScript will not be able to access it. This means that requests can be sent to the server and the requested actions will be executed (hence the write only), but the JavaScript won’t be able to read the responses. This will stop the attacker to first request a form on the website to read the CSRF-protection-token and then submit the form with the token, because it won’t be able to read the response.

withCredentials vs. Access-Control-Allow-Origin: *

This is an interesting limitation which is actually quite smart. If you send a request with credentials and the server responds with Access-Control-Allow-Origin: *, which allows every domain, then you will not see the response content from JavaScript. The reason is that the ‘withCredentials’ cannot be used if all origins are allowed. This is the last line of defense against CSRF. If you could read the response, that would break the 99% of CSRF protections, because you could first load a page with you credentials, steal the CSRF token, then do a CSRF with the token.

5) Summary

Although these different perspectives are a little redundant, but all the different attack scenarios can be built from the combination of them.

Since this is only my quick analysis, if you have other ideas to the topic let me know.


  1. hello,where can i get the ppt or video.thanks

  2. geri

    November 26th, 2013 at 23:44

    Hi litdg,

    you find the slides here. I think video is not yet available, but I will write a post if the Hacktivity team is ready with it.

    All the best!

Leave a Reply

Your email address will not be published.



© 2023 Æther Security Lab

Theme by Anders NorenUp ↑