0

This is a concept that I thought I understood, but recently found out I had all wrong. I've looked all around the internet and find plenty of examples of small details and code snippets, but I still lack an understanding of what it prevents and why it prevents it and for whose sake. So this is more of a request for a high-level explanation than a question.

Anyways, here's what I THINK I understand about it:

Let's say I have domain A.com and domain B.com. Each on their own apache servers with their own IP addresses. I load an html file from domain A.com into a browser. The browser executes a POST XMLHttpRequest to B.com/doStuff.php, which fails because the same-domain-policy was set.

So: Who's same-domain-policy is relevant? I think the answer is B.com/doStuff.php's... right? So when A sends the request, B checks the request headers for an origin and says "whoops, different domain, won't listen to you". Or does A send the request, B responds with headers that specify "same-domain-policy", and then the browser checks that because same-domain-policy was specified, and the domain from the headers of the A request don't match the one from the B request the BROWSER refuses to send out the xhr?

If that's the case, it seems that the point of not allowing cross-origin-requests is because "I don't want anyone other than me accessing my API". Is that all? Because wouldn't you want to solve that with some kind of authentication instead? Couldn't someone just construct an HTTP request with a fake origin header (simply lie)?

Or is this somehow supposed to protect the user? If that's the case, how is preventing them from calling your API ever going to protect anyone?

I'm so confused...

Phildo
  • 986
  • 2
  • 20
  • 36
  • it doesn't stop machines from grabbing the url using, for example, curl, it only tries to stop browser-based fetching. to block non-js threats, you must authenticate. the point is that a site's content cannot be re-embedded by unsigned JS without you explicitly allowing it. – dandavis Jan 13 '14 at 21:24
  • @dandavis isn't that super easy to sidestep then? just have the javascript request that your server gets it (with curl for example) and then passes it back to the javascript... what's the point? – Phildo Jan 13 '14 at 22:34
  • the point is control and accountability: servers/php codes are registered to a credit card, plain old webpages are not. in your example, the server performing the curl could be easily identified and blocked, but if the traffic was coming from ad-injected javascript, the request could be coming from everywhere... – dandavis Jan 13 '14 at 23:10
  • @dandavis - but if we're relying on modern browsers being compliant in the origin headers they're sending for this to work anyways, then the origin of the malicious javascript could be equally easily found (it would be sent in the header of the HTTP request), no? – Phildo Jan 14 '14 at 02:51
  • for compromised ads, the js would be loading content on your domain from potentially thousands of other domains. SOP is supposed to protect copyrighted material from being invisibly mashed-up and presented without ads. It's not the most comprehensive policy in the world, you can still submit forms anywhere, load images and script from anywhere, use jsonp, etc. It's really more of an artifact from the early web that is taken as a given by every web pro. CORS loosened it in an opt-in basis instead of just removing the restriction completely. it prevents swarms of zombies and is what it is... – dandavis Jan 14 '14 at 04:36

2 Answers2

1
Who's same-domain-policy is relevant?

The server receiving the request decides.

... the BROWSER refuses to send out the xhr?

No, the server refuses to respond. To be more exact, in modern browsers it is done by preflighted requests. It means that for each cross-origin request, first an OPTIONS request is sent automatically by the browser whose headers are the exact same as the intended request will have but with no request body. The server responds also with headers only. Access-Control headers in the response will let the client browser know whether the request would be fulfilled according to the server's policies. In a sense the browser is preventing the request, but only because it already exchanged a request/response pair with the server and knows that there would be no point to attempt the request. If you forge a request in such a case, the server will still deny serving it.

marekful
  • 14,986
  • 6
  • 37
  • 59
  • Ok so that makes sense. Thank you for clarifying that! BUT- am I then correct that the only purpose for this whole thing is to disallow people accessing your API, but only specifically through javascript? (IE- your API can still be accessed by anything else, and the only reason javascript can't do it is because browsers don't support a way for JS to edit it's origin header?). Who is that protecting? Your API can still be accessed- it just requires a simple workaround (tell your server to make the call, then pass it back to your js). – Phildo Jan 13 '14 at 21:54
  • "just requires a simple workaround" is a not-so-small "just", and it's that distinction alone that forms the bedrock of basic client-side web security. a php server can be shut down, a rouge script is much harder to extinguish and poses a far larger problem than a curl or php anyone and their brother can write. – dandavis Jan 13 '14 at 23:14
  • @dandavis - the bedrock of basic client-side web security?! if there exists a workaround that I (an admitted newbie) could easily exploit (which again, might not be the case- I'm still waiting/hoping to be corrected though...), the client side web is screwed! At best this seems to just be a front lines barrier to lazy hackers...? If that's all it is, then so be it. But I feel like I'm consistently hearing chatter as though this kind of thing is a big deal. (And I truly mean no disrespect- I'm just still struggling to grasp all this, and am convinced there's SOMETHING I'm still missing...) – Phildo Jan 14 '14 at 02:55
0

The idea is that you don't want to access server b from server A via Javascript. If you're interacting with an API, you would use javascript to make a call to your own server's backend code, which would then make a call to the other server.

Andrew Clark
  • 279
  • 1
  • 3
  • but WHY? "I don't want someone accessing my API from javascript, but if they do it from PHP its ok" seems like an entirely superficial reason to justify this infrastructure... – Phildo Jan 13 '14 at 21:49