I have a website www.foo.com:8002 that I have resolve to in my hosts file. I have another (the main site) running at localhost:80

In www.foo.com:8002 the page looks like

<form name="myform" action="http://localhost/bar" method="post">
  <input type="hidden" name="some" value="value" />
<script> document.myform.submit() </script>

I expected for the request to go through and the browser (Chrome) to not read the response since it violates the same origin policy. However, it turns out that the browser receives the response and displays the contents perfectly fine. How is this possible?

  • 4
    I don't really understand your question. It sounds like you just rediscovered CSRF, but you know the term so... I don't get it. – Luc Aug 27 '12 at 23:11
  • 1
    @Luc "It sounds like you just rediscovered CSRF, but you know the term so..." Not only. He knows the term "same origin policy", but does not know what it means. – curiousguy Aug 28 '12 at 7:24
  • "the browser (Chrome) to not read the response" Why? What would you ignore the response of a request you made? What security property would you expect from that? – curiousguy Aug 28 '12 at 7:32

Ahh! I think I can explain.

  • foo.com can navigate the browser to any page or domain. Thus, foo.com can submit a form that posts to localhost, even though that's a different domain. No problem.

  • After navigating to a new page, the browser will happily display the contents of the new page to the user. For instance, after submitting the form to localhost, the browser will happily display the response from localhost to the user.

    This is not a same-origin policy violation, because the response is shown to the user, not to foo.com. The user is trusted and is not restricted by the same-origin policy. The same-origin policy only restricts websites, not the user.

  • At no point does foo.com get to read the response from localhost. The browser will show the response from localhost on the screen, but foo.com can't read it. That is what the same-origin policy forbids.

So, in summary: the same-origin policy doesn't prevent one site from navigating the browser to another site. It doesn't prevent one site from triggering a request to another site. However, it does prevent the first site from reading the response to that request to the second site.

| improve this answer | |

That is the point of CSRF, your browser makes the request as if it was initiated by a user. In a real CSRF attack situation the GET or POST will be inside in invisible iframe so that the victim isn't aware that they have been compromised.

In this case the attacker's JavaScript or ActionScript running on the victim's browser cannot read the response of the forged cross-site request.

That being said, you should read part 2 of the browser security handbook and seriously consider picking up a copy of The tangled web.

| improve this answer | |
  • 1
    I thought in CSRF attacks, the browser can POST to a server, but since it is cross domain you won't be able to read the response. And that is why CSRF attacks only concern themselves with requests that cause side effects (and why idempotent GETs are safe) – Jarrod Everett Aug 28 '12 at 1:37
  • @Jarrod Everett yes that is absolutely correct... however a victim's browser performs the CSRF attack, not the attacker's browser. – rook Aug 28 '12 at 5:08
  • @Jarrod Everett the attacker's javascript or actionscript running on the victim's browser cannot read the response. – rook Aug 28 '12 at 5:12
  • @JarrodEverett, be careful: who do you mean by "you"? That pronoun is a bit ambiguous. Site X can trigger the browser to POST to site Y (that's how a CSRF attack works). Since it is cross-domain, site X cannot read the response from site Y. However, the user can read the response (since the response will be displayed on the screen). (This is entirely consistent with everything you reported in your question, by the way.) – D.W. Aug 28 '12 at 6:15

The command document.myform.submit() triggers a browser action and navigation event. This means it is not restricted by the same origin policy. If instead you had tried to send the request as an XHR and interpret the result using the same running JS code, then you might have run into difficulty.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.