Understanding XMLHttpRequest over CORS (responseText)

75,820

Solution 1

For a "simple" HTTP verb like GET or POST, yes, the entire page is fetched, and then the browser decides whether JavaScript gets to use the contents or not. The server doesn't need to know where the requests comes from; it is the browser's job to inspect the reply from the server and determine if JS is permitted to see the contents.

For a "non-simple" HTTP verb like PUT or DELETE, the browser issues a "preflight request" using an OPTIONS request. In that case, the browser first checks to see if the domain and the verb are supported, by checking for Access-Control-Allow-Origin and Access-Control-Allow-Methods, respectively. (See the "Handling a Not-So-Simple Request" on the CORS page of HTML5 Rocks for more information.) The preflight response also lists permissible non-simple headers, included in Access-Control-Allow-Headers.

This is because allowing a client to send a DELETE request to the server could be very bad, even if JavaScript never gets to see the cross-domain result -- again, remember that the server is generally not under any obligation to verify that the request is coming from a legitimate domain (although it may do so using the Origin header from the request).

Solution 2

So is it just the browser and Javascript that is blocking responseText from being used in any substantial way even though it's actually transferred?

Yes. You can make any request you like with JS.

It is access to the data that the same origin policy prevents.

Requests which do malicious things (such as "POST http://bank.example/give/money?to=attacker" or "POST http://forum.example.com/post?message=spamspamspamspam") are called CSRF attacks and have to be defended against by the server.

Share:
75,820

Related videos on Youtube

AreYouSure
Author by

AreYouSure

Updated on July 09, 2022

Comments

  • AreYouSure
    AreYouSure almost 2 years

    For a project I'm looking at various HTML5 and Javascript elements and security around them and I'm trying to get my head around CORS just now.

    Based on my testing, if I remove..

    <?php
     header("Access-Control-Allow-Origin: *"); 
     header('Access-Control-Allow-Methods: GET, POST, OPTIONS');
     ?>
    

    ..from the page that is trying to be accessed I see the following in the console log on Chrome:

    XMLHttpRequest cannot load http://www.bla.com/index.php. Origin http://bla2.com is not allowed by Access-Control-Allow-Origin.
    

    I understand this to be correct, however Wireshark shows HTTP/1.1 200 OK in the return and in the data shows the source of the page being requested. So is it just the browser and Javascript that is blocking responseText from being used in any substantial way even though it's actually transferred?

    The code is just as below:

      function makeXMLRequest() {
      xmlhttp=new XMLHttpRequest();
    xmlhttp.onreadystatechange = function() {
        if (xmlhttp.readyState==4) {
            alert(xmlhttp.responseText);
        }
    }
    xmlhttp.open("GET","http://www.bla.com/index.php",true);
    xmlhttp.send();
    }
    

    Thanks in advance.

  • Kaspars Foigts
    Kaspars Foigts over 10 years
    What happens when XMLHttpRequest.withCredentials is set? Credentials are not sent if response does not contain Access-Control-Allow-Credentials. This calls for preflight check even on simple GET requests, but I don't see any in server logs.
  • GtiClicker
    GtiClicker about 3 years
    So where would I put Access-Control-Allow-Origin?
  • Quentin
    Quentin about 3 years
    @GtiClicker : The place it is in the question (before it was removed) is fine
  • GtiClicker
    GtiClicker about 3 years
    But I am using fetch not XMLHttpRequest
  • Quentin
    Quentin about 3 years
    @GtiClicker — So what? The code in the question doesn't put Access-Control-Allow-Origin in the code that touches XMLHttpRequest. (If you have a new question, then ask a new question. Don't just comment on a tangentially related answer).