Same Origin Policy (SOP) - Lab 1
What is SOP❓
The same-origin policy is a web browser security mechanism that aims to prevent websites from attacking each other.
The same-origin policy restricts scripts on one origin from accessing data from another origin.
In other words, it’s a policy that prevents javascript (JS) from accessing resources that belong to different origin. Before we talk on why we need to learn about SOP. Let’s understand what an origin is.
So, what is an origin❓
Two URLs have the same origin if the protocol, port, and domain (not subdomains) are the same for both URLs.
For example, consider this URL:
https://secure-cookie.io
This URL consists of
- protocol:
https
- domain:
secure-cookie.io
- default port number:
443
The following table shows if a given URL has the same origin as the above URL:-
URL | Same Origin? |
---|---|
http://secure-cookie.io |
❌Different protocol and different port |
https://www.secure-cookie.io |
❌Different domain |
https://csrf.secure-cookie.io |
❌Different domain |
https://secure-cookie.io:8080 |
❌Different port |
https://secure-cookie.io/login |
✅Same protocol, domain, and port |
⚡ Lab 1 : Why do we need SOP?
Without SOP, if you visit a malicious website, it would be able to read or modify the contents of your bank account, read your emails from GMail, private messages from Facebook, etc.
Let’s see how SOP stops such attacks 🔥
-
Assume an attacker tricked you to visit this page.
-
The page contains a login page, assume that it looks identical to your bank login page!
right click anywhere in the page and
view page source
you should see:-
<iframe id="CSRFlogin" src="https://csrf.secure-cookie.io/login"</iframe>
-
Using an iframe element, an attacker can nest HTML page into attacker website. Here the attacker is embedding a login page from
https://csrf.secure-cookie.io/login
.💡 In real world the attacker will use your real bank account login url.
-
In the page source code, you can also see there’s a JS snippet
<script>
window.onload = function() {
login_form = document.getElementById('CSRFlogin').contentWindow.document.forms[0]
username = login_form[0].value
password = login_form[1].value
console.log(username,password)
};
</script>
This code 👆 will try to access the HTML form
elements like username/password and
then print them in the console. The attacker can send this data to a
server of his control. But i wanted to keep the code simple.
- As soon as you load this page, your browser (I’m using Firefox) will throw this security violation in the console:-
Uncaught DOMException: Permission denied to access property “document” on cross-origin object
This exceptions simply means that SOP prevents a malicious javascript in origin
https://s3.eu-west-1.amazonaws.com
from accessing data in origin
https://csrf.secure-cookie.io
yaaaaay! 🎉🎉🎉🎉
In this lab, we used iframe, however SOP applies on iframe as well as AJAX (an old term and it just means making HTTP requests from javascript).
🔎 Deep dive - SOP Rules
As we saw, same-origin policy controls interactions between two different origins. Front-end developers usually use Javascript API such as XMLHttpRequest or fetch to make HTTP requests to backend APIs.
If the HTTP request is for same origin, then no worries. SOP will allow it and it will work.
If the request is cross-origin (to a different origin), then depending on the type of the request, SOP does allow certain cross-origin requests.

Let’s put the cross-origin types in a table.
Interaction type | Result |
---|---|
read: reading data from an endpoint, such as json data. | ❌ Disallowed |
write: sending data to an endpoint, such as password reset request. | ✅ Allowed (as long as it’s a simple request) |
embedding: embedding resource, such as image/video using HTML element. | ✅ Allowed (as long as crossorigin attribute is not set) |
The best way to understand each type is to play with it.

There’s a separate lab for each category 😉.
See you there!