points by tgsovlerkhgsel 6 years ago

Even a JavaScript initiated POST request will go through. Blocking it would not make a lot of sense, because the attacker could just use the FORM (possibly in an iframe to keep it invisible to the victim).

It is possible that XHR, or common XHR libraries, default to adding some header that makes it a non-standard request, but a fetch() call works.

In Firefox, open a debug console and run

    fetch('https://otherorigin.example.com', {method: 'POST', body: 'blah'})

You will see two things. In the console:

    Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://otherorigin.example.com/. (Reason: CORS request did not succeed).

In the network tab, a HTTP request.

Replace with a URL of a server you control, or run `nc -lnvp 9999` and replace the URL with http://127.0.0.1:9999, to see that the request is indeed being made.

As the author said... few people understand CORS.

avisser 6 years ago

Bad naming strikes again? The message "Request Blocked" means something unambiguous to me. And it doesn't mean "I made the request, but won't let you see the response."

pixelperfect 6 years ago

But for XHR only POST requests that meet a lot of constraints (defined here https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Simpl...) will work, right?

Nothing with a Cookie header for example...

  • Thorrez 6 years ago

    That page says that the Cookie header cannot be "manually set". Headers can still be automatically sent, and the browser can automatically send cookies from the cookie jar. So for example this will not send a request with the manually set cookie:

        r = new XMLHttpRequest();
        r.withCredentials = true;
        r.addEventListener('load', function(e) {console.log('loaded: ', this, e);});
        r.addEventListener('error', function(e) {console.log('error: ', this, e);});
        r.open('GET', 'https://www.google.com');
        r.setRequestHeader('Cookie', 'somecookie=somecookievalue')
        r.send();
    

    But this will send a request with the automatically set cookies just fine:

        r = new XMLHttpRequest();
        r.withCredentials = true;
        r.addEventListener('load', function(e) {console.log('loaded: ', this, e);});
        r.addEventListener('error', function(e) {console.log('error: ', this, e);});
        r.open('GET', 'https://www.google.com');
        r.send();
    

    Assuming the user is already logged in to bank.com , the user's cookies will be automatically sent on the request, and the transfer will go through assuming there is no CSRF protection.

joshschreuder 6 years ago

TIL. Thank you for teaching me something - I had no idea the request still went through and it was just the response being blocked.

aaronharnly 6 years ago

Thank you, I stand corrected! Editing :-)