4 ms·
I know you know this, but to clarify steps 2/3: - Evil tries to make an HTTP request to bank.com/transfer.php If this is a regular HTTP POST (ie submitting a
by aaronharnly 7y ago
I know you know this, but to clarify steps 2/3:
- Evil tries to make an HTTP request to bank.com/transfer.php
If this is a regular HTTP POST (ie submitting a form, and the browser window changes location), the browser will allow it.
If this is an xhr POST, the browser, following the same-origin policy, allows the request, but prevents accessing the response (unless allowed with CORS).
[EDITED with tgsovlerkhgsel's help!]
- metafunctor 7y agoHow hard is it to trigger a regular HTTP POST instead of an xhr POST?
- Thorrez 7y agoNot hard. Just make an html form with the values you want, then with javascript call document.getElementById("myForm").submit();
- tgsovlerkhgsel 7y agoEven 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 http://127.0.0.1:9999, to see that the request is indeed being made. As the author said... few people understand CORS.
- aaronharnly 7y agoThank you, I stand corrected! Editing :-)
- pixelperfect 7y agoBut for XHR only POST requests that meet a lot of constraints (defined here https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Simple_requests https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Simpl...) will work, right? Nothing with a Cookie header for example...
- Thorrez 7y agoThat 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 7y agoTIL. Thank you for teaching me something - I had no idea the request still went through and it was just the response being blocked.
- avisser 7y agoBad 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."