Search code examples
ajaxsecuritypostcsrfsame-origin-policy

Do browsers allow cross-domain requests to be "sent"?


I am newbie to website security and currently trying to understand Same-Origin-Policy in some depth. While there are very good posts on stackoverflow and elsewhere about the concept of SOP, I could not find updated information on whether chrome and other browsers allow cross-domain XHR post requests to be 'sent' from the first place.

From this 5 year old post, it appears that chrome allows the request to pass through to the requested server but does not allow reading the response by the requester.

I tested that on my website trying to change user info on my server from a different domain. Details below:

  1. My domain: "www.mysite.com"
  2. Attacker domain: "www.attacker.mysite.com" According to Same-Origin-Policy those two are considered different Origins.
  3. User (while logged in to www.mysite.com) opens www.attacker.mysite.com and presses a button that fires a POST request to 'www.mysite.com' server...The submitted hidden form (without tokens in this case) has all the required information to change the user's info on 'www.mysite.com' server --> Result: CSRF successful attack: The user info does indeed change.

  4. Now do the same but with javascript submitting the form through JQuery .post instead of submitting the form--> Result: Besides chrome giving the normal response:

No 'Access-Control-Allow-Origin' header is present on the requested resource

, I found that no change is done on the server side...It seems that the request does not even pass through from the browser. The user info does not change at all! While that sounds good, I was expecting the opposite.

According to my understanding and the post linked above, for cross-domain requests, only the server response should be blocked by the browser not sending the post request to the server from the first place. Also, I do not have any CORS configuration set; no Access-Control-Allow-Origin headers are sent. But even if I had that set, that should apply only on 'reading' the server response not actually sending the request...right?

I thought of preflights, where a request is sent to check if it's allowed on the server or not, and thus blocking the request before sending its actual data to change the user info. However, according to Access_Control_CORS , those preflights are only sent in specific situations which do not apply to my simple AJAX post request (which includes a simple form with enctype by default application/x-www-form-urlencoded and no custom headers are sent).

So is it that chrome has changed its security specs to prevent the post request to a cross domain from the first place? or am I missing something here in my understanding to the same-origin-policy?

Either way, it would be helpful to know if there is a source for updated security measures implemented in different web browsers.


Solution

  • OK...I got it...It's neither a new policy in chrome nor missing something in SOP... The session cookies of "www.mysite.com" were set to "HttpOnly" which means, as mentioned here, that they won't be sent along with AJAX requests, and thus the server won't change the user's details in point (4).

    Once I added xhrFields: { withCredentials:true } to my post request, I was able to change the user's information in a cross-domain XHR POST call as expected.

    Although this proves the already known fact that the browser actually sends the cross-domain post requests to the server and only blocks the server response, it might still be helpful to those trying to deepen their understanding to SOP and/or playing with CORS.