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.
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.
Share Improve this question edited Jun 20, 2020 at 9:12 CommunityBot 11 silver badge asked Jun 19, 2018 at 16:35 MagnusMagnus 7,82914 gold badges65 silver badges101 bronze badges 5- Writes generally means HTTP requests. This means in either direction. – SLaks Commented Jun 19, 2018 at 16:37
-
1
A cross-origin write is something like a
<form>
post to a different domain. Those are allowed by the browser, and are the reason that browsers alone do not solve your CSRF problems. – Pointy Commented Jun 19, 2018 at 16:40 - 1 It's worth remembering that MDN is collaboratively edted by the munity. I don't think I'd've used the word "writes" there. It generates more confusion than it alleviates. – T.J. Crowder Commented Jun 19, 2018 at 16:48
-
@Pointy Is it necessary to check for an unguessable
CSRF
token whenever reading form data sent from another domain then? EDIT: I guess that makes sense, to avoid reading from malicious source. I haven't actually implemented such munication, so not sure how it is done / if my question makes sense. – Magnus Commented Jun 19, 2018 at 17:37 - A CSRF token can be an explicit part of a form, or it can be added to XHR request headers. Whatever it is, it should not be possible for a third-party domain to read page content from your site that exposes the token. Generally, some secured value is used, unique for each user session. – Pointy Commented Jun 19, 2018 at 20:47
2 Answers
Reset to default 12MDN 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.
can have this:
<form action="https://google./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.
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)
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:
- reading the already loaded resource of originA from within originB in the browser
- 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 plex, there're quite a few cases requests being initiated from within one origin to another, for now as far as I can list:
- the
<a href=...
linking(writes) to a different site - the
<form action=... method="POST">
that posts(writes) to a different site - the
<link rel="stylesheet" href="…">
that loads CSS style from a different site and embeds it into the origin page - the
<img>
tag that loads an image elsewhere and embeds it into the original page - the
<script>
which loads javascript code snippet elsewhere and embeds it into the original page XMLHttpRequest
AJAX request- Web Fonts (for cross-domain font usage in @font-face within CSS)
- WebGL textures.
- Images/video frames drawn to a canvas using drawImage().
- 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/)