Same-Origin Policy: Writes Allowed?

I am struggling a bit with MDN's description of the same-origin policy.

They state that:

Cross-origin writes are typically allowed....

Cross-origin embedding is typically allowed....

Cross-origin reads are typically not allowed...

I understand the second bullet allows standard embedding of cross-origin content (say from CDN), into a site:

  • <script src="...">
  • <link rel="stylesheet" href="...">

But, what is meant by writes are allowed, reads are not allowed? Does "writes" refer to my site writing to another site, or the opposite direction? Same with "read", what direction are they talking about there? Some examples would be greatly appreciated.


Solution 1:

MDN gives examples of what it means by writes:

Examples are links, redirects and form submissions. Certain rarely used HTTP requests require preflight.

So for instance, my site at example.com can have this:

<form action="https://google.com/search" id="kittens-form" target="_blank">
<input type="hidden" name="q" value="kittens">
</form>

...and do this:

document.getElementById("kittens-form").submit();

Example on jsFiddle

(In that specific case, since I have target="_blank", I'd have to do it in response to a user action or I'd trip over the popup blocker. But if I don't open a new window, I can do it any time I like.)

Same with "read", what direction are they talking about there?

They're talking about code running in origin A reading information from origin B. So my malicious example.com site can't read from your bank's website without your bank specifically allowing it via CORS (this is so I can't steal information about your bank account, since you may have a valid banking session running...).

More in this question's answers: Same origin Policy and CORS (Cross-origin resource sharing)

Solution 2:

I finally made myself clear after having been struggling half a hour about this saying:

  • Cross-origin writes are typically allowed....
  • Cross-origin embedding is typically allowed....
  • Cross-origin reads are typically not allowed...

It classifies the same-origin problems into three types, but, depending on whether interacting with the server, I'd prefer to classify the same-origin policy into two types:

  1. reading the already loaded resource of originA from within originB in the browser
  2. requesting the remote resource of originA from within originB in the browser

The first corresponds the "Cross-origin reads" case of the above quotes and the second corresponds the "Cross-origin writes" and "Cross-origin embedding". (so yes, you get that both "writes" and "embedding" actually mean requesting resources from remote server instead of directly reading from local)

The first type is simple to handle: the browser definitely block it. So that a javascript snippet of websiteA cannot read the cookie set by websiteB - thus ensures the safety of our web accounts.

The second type is somewhat complex, there're quite a few cases requests being initiated from within one origin to another, for now as far as I can list:

  1. the <a href=... linking(writes) to a different site
  2. the <form action=... method="POST"> that posts(writes) to a different site
  3. the <link rel="stylesheet" href="…"> that loads CSS style from a different site and embeds it into the origin page
  4. the <img> tag that loads an image elsewhere and embeds it into the original page
  5. the <script> which loads javascript code snippet elsewhere and embeds it into the original page
  6. XMLHttpRequest AJAX request
  7. Web Fonts (for cross-domain font usage in @font-face within CSS)
  8. WebGL textures.
  9. Images/video frames drawn to a canvas using drawImage().
  10. CSS Shapes from images.

In which , the browser allows the 1-5 cases while blocks 6-10, there might be 11, 12, ... cases in the future that are blocked by browsers, this Mozilla page could be a better place to keep up with the new blocking cases in the future.


(initially post on: https://cifer76.github.io/posts/same-origin-policy/)