What is the same-origin policy?
First, what is an origin?
An origin is the combination of URL scheme, host, and port. Here are some examples of origins:
Origin | Scheme | Host | Port |
---|---|---|---|
https://example.com | https | example.com | 443 (default port of https) |
http://example.com | http | example.com | 80 (default port of http) |
http://example.com:8080 | http | example.com | 8080 |
The path in the host doesn’t matter. So, the following origins would be considered the same:
- https://example.com
- https://example.com/foo
- https://example.com/foo/bar
Okay, what is the same-origin policy?
The same-origin policy refers to the standardized behaviour of web browsers to prevent scripts hosted on one origin (e.g., https://foo.com
) from accessing data hosted on another origin (e.g., https://bar.com
).
What problem is it trying to solve?
Let’s consider what could happen if the same-origin policy wasn’t applied.
A world without the same-origin policy
- You are logged into your bank account at
https://mybank.com
- You browse to another website:
https://someforum.com
. - Unknown to you, when you access
https://someforum.com
, the website initiates an Ajax request tohttps://mybank.com/my-account-details
, reads the response and sends it to be stored on some server. - Your bank account details have been compromised!
Now, let’s consider how the same-origin policy mitigates this risk.
A world with the same-origin policy
- You are logged into your bank account at
https://mybank.com
- You browse to another website:
https://someforum.com
. - Unknown to you, when you access
https://someforum.com
, the website initiates an Ajax request tohttps://mybank.com/my-account-details
. - The browser sees that the request origin
https://someforum.com
is not the same as the resource origin (https://mybank.com
) and that the server hasn’t made an exception forhttps://someforum.com
via CORS so it denies the script access to the response fromhttps://mybank.com
. You get a JavaScript error like the following:Access to XMLHttpRequest at 'https://mybank.com/my-account-details' from origin 'https://some-forum.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
But can’t malicious scripts fake the Origin
header?
Not from the browser. The Origin
header is a forbidden header name which means it cannot be modified via JavaScript running in the browser.
But you can fake the Origin
header outside the browser, with CURL for example. But in this case, the request won’t have access to the browser cookies so the scope of attacks is reduced. For example, a malicious script won’t be able to utilize cookie-based authentication.
Sources
Thanks for your comment 🙏. Once it's approved, it will appear here.
Leave a comment