Same Origin policy
As per the documentation in Mozilla Web Docs
It helps isolate potentially malicious documents, reducing possible attack vectors. For example, it prevents a malicious website on the Internet from running JS in a browser to read data from a third-party webmail service (which the user is signed into) or a company intranet (which is protected from direct access by the attacker by not having a public IP address) and relaying that data to the attacker.
Now before diving deep into this, let us take a second to understand what an Origin is and why it is so important.
How the browser compares two different origins
Let's assume that the we are in
http://www.example.com/dir/page.html, following table exhibits how browsers compare the origins:
Action Time !!!
On the left you'll see the source code that is actually trying to make a HTTP request to
mail.google.com. On the right is a browser loaded with our malicious HTML code.
We can see that our browser has restricted us from accessing
mail.google.com, since our origin
http://127.0.0.1:5500/exploit.html is not same as
OK but ! I saw a request going out to
mail.google.com in my Network tab in Developer Console, so what does that even mean ???
To answer your question, this is called as a
pre-flighted request made by our browser to check whether we are allowed to access the target resource. But we can see it returned a
CORS error, CORS stands for
Cross Origin Resource Sharing.
It is a security mechanism in which browsers will make a
OPTIONS request to the specified resource and checks for some headers in the HTML response. These headers are then interpreted by browsers, following are few of the headers browsers normally look for before making an actual request:
- Access-Control-Allow-Origin : Tells the browser whether the mentioned origin can access the resource or not.
- Access-Control-Allow-Credentials: Tells the browser if it is allowed to send cookies along with the request.
- Access-Control-Allow-Methods : This is an interesting part which we will talk about in the upcoming blog posts. For now just know that this allows the browser to send custom headers along with the request.
Our browser performs the following steps to check if we can access the resource in mentioned origin
It will compare our current origin with the target resource's origin, our browser will go ahead and get the resource for us only if it find both origins to be same.
If not, it will make a pre-flight request to check CORS policy of the target resource.
In our case
mail.google.com does not match the
Same Origin Policy and also the remote server hasn't returned any of the mentioned headers in the HTML response. So this means a big
NO from the server; to access
Wait a Minute !!!
If you closely look at the following image, the line just before the CORS error
What ?? We actually made a
GET request to
<img> tag, but is this a bypass for CORS ?? Check out the References section at the end of this post for more information on this.
We will talk more about this on upcoming blog posts. If you are really keen to know this right now, start your quest by searching for what is
CSRF and how can we mitigate it. Happy hacking !!
Refer : Wikipedia on Same origin policy
It is very important to remember that the same-origin policy applies only to scripts. This means that resources such as images, CSS, and dynamically-loaded scripts can be accessed across origins via the corresponding HTML tags (with fonts being a notable exception). Attacks take advantage of the fact that the same origin policy does not apply to HTML tags.
Refer: MDN Docs on Preflight request
A CORS preflight request is a CORS request that checks to see if the CORS protocol is understood and a server is aware using specific methods and headers.
It is an OPTIONS request, using three HTTP request headers: Access-Control-Request-Method, Access-Control-Request-Headers, and the Origin header.
A preflight request is automatically issued by a browser and in normal cases, front-end developers don't need to craft such requests themselves. It appears when request is qualified as "to be preflighted" and omitted for simple requests.