Browser Policies | Part-2
Same Origin Policy (SOP)
author
Written byLakshit NagarPrinciple Software Developer@Oracle India (Ex-ThoughtWorker, IIT Kanpur Alumni)
Browser Policies | Part-2
Same Origin Policy (SOP)
author
Written byLakshit NagarPrinciple Software Developer@Oracle India (Ex-ThoughtWorker, IIT Kanpur Alumni)

Intended Audience

This article is written by a software developer for anyone who is interested in the technical aspects of modern web browsers. To understand this article, readers need to know the overview of browser's policies. Here is the article on the browser-policies-part-1-technical-overview-of-browser-policies.

Content

  1. Introduction
  2. Why we need Same Origin Policy?
  3. Default behaviour of Same Origin Policy?
  4. Exclusions from Same Origin Policy?
  5. How to enable Same Origin Policy?
  6. How to relax Same Origin Policy?
  7. Attacks prevented by Same Origin Policy?
  8. Conclusion


Introduction

Same-Origin-Policy is one of the browser's policies that make browsers a safe place to browse the Internet.

Under this policy browser prevents a script running inside an origin to interact with other origin with some exceptions. We can use an egg crate for an analogy, where each egg represents an origin (browser's tab). Like no two eggs in the crate touches each other in a same way no two origin can interact with each other through a script. Browser Same Origin Policy


Why we need Same Origin Policy?

Lets assume a normal user's scenario. A user uses a browser for online banking. After doing some stuff, that user forget's to logout and closes the tab. However, user closed that tab, but session is still active at the server.

Now if he/she opens a malicious website which contains a script that makes an api call to the bank's server with all the required session cookies. Bank's server thinks that the real user is making this call and approves the request. Now that malicious website can do whatever it wants. This is scary. Isn't it?

This is the reason browser enforces same origin policy, that no two origin can interact through script any way. Cross Origin Request Illustration


Default behaviour of Same Origin Policy

It is crucial to understand that same-origin-policy applies only to the code written in the script. So by default any attempt to access another origin through code written inside the script is not allowed. However we can load and execute a script from another origin but it should not contain any such code which tries to interact with another origin, otherwise it will throw error.

Cross origin API call

For example a script containing a code to make api to call to another origin, simply throws a CORS error similar to below:

script.js (origin: http://localhost:3001)

fetch('http://localhost:3002/app')
Browser CORS Error

Cross origin document access

Another example to access another origin is through iframes or popup. If we try to access document across origin, it will be null:

script.js (origin: http://localhost:3001)

<iframe id="cross_origin_iframe" src="http://localhost:3002"> </iframe>

<script>
  var cross_origin_iframe = document.getElementById("cross_origin_iframe");
  console.log(cross_origin_iframe.document) // null
</script>

Important Note:

Same-Origin-Policy applies only to actual script. It does not apply to HTML tags such as <script src="cross_origin_url.js">, <img src="cross_origin_url.png">, <link href="cross_origin_url.css">, etc.


Exclusions from Same Origin Policy

All the HTML tags are excluded from the same origin policy (exception to font). This means that resources are accessed across origins via corresponding HTML tags. Therefore, following cross origin embeddings are allowed:

<script src="cross_origin_url.js">  // Allowed ✅ 

<img src="cross_origin_url.png">  // Allowed ✅ 

<link src="cross_origin_url.css">  // Allowed ✅ 

<iframe src="cross_origin_url.html">  // Allowed ✅ 

<script src="cross_origin_url.js">  // Allowed ✅ 

@font-face {
  font-family: "Open Sans";
  src: url("cross_origin_url.woff2");  // Not Allowed ❌ 
}

Apart from HTML tags, there is one more exclusion from SOP. That is communication instead of accessing. We can communicate with other origins via postMessage or MessageChannel or BroadcastChannel API.


How to enable Same Origin Policy?

There is nothing extra we need to do here, in order to enable SOP. As long as we are on a trusted browser, it is enabled by default by the browser. Therefore any access via script to other origin is simply not allowed.


How to "relax" Same Origin Policy?

Browser Policies Relax SOP We have seen the default behaviour of the SOP. However we can bypass the SOP without "technically" violating the SOP. Therefore the heading mentions "relax" instead of bypass. Following are the ways in we can relax the SOP:

document.domain

The document loaded by an origin contains an interesting property .domain. This property tells what is the domain of the origin. Javascript has access to modify it. If the script in both the origins changes this domain property to a common origin, technically both will be on same origin because the protocol and the port are mostly same for all websites.

// orders.example.com
document.domain = example.com

// catalog.example.com
document.domain = example.com
Therefore, cross origin document access is allowed.

Cross-Origin Resource Sharing (CORS)

CORS is most popular and practical way to relax SOP. CORS standard allows controlling SOP via HTTP response (to be set on the server) header: Access-Control-Allow-Origin. This header allows an explicit list of origins, you want to allow interact with your own origin.

// orders.example.com
HTTP/1.1 200 OK
Server: Apache/2
Access-Control-Allow-Origin: catalog.example.com

// catalog.example.com
Now we can intereact with orders.example.com from catalog.example.com

Cross-Document Messaging

The two types of cross origin interactions we learned so far Cross origin API call and Cross origin document access in above sections, need follow SOP. There is third type of interaction (communication more precisely) via event messaging does not need to follow SOP. This is because, with this method, the communication is setup through mutual consent between both the origins.

For this, browsers exposes multiple APIs. The most used one is postMessage API. There are other APIs such as MessageChannel and BroadcastChannel API. If you want learn more about cross origin event messaging please read separate articles on the same: postMessage or MessageChannel or BroadcastChannel API.

JSONP (JSON with Padding)

Since, SOP does not apply to HTML elements (Like <script> tags), we usually load scripts from another origins. Like this:

<script src="https://another-origin.com/api"></script>
But can we load any data (like .json) through this technique? The answer is NO! Because <script> tag only understands .js files.

JSONP here is the trick to receive .json data. The process is extreamly simple. Intead of sending data in a JSON format, just wrap it around a function call signature.

// Traditional JSON
{
  "roses": "red",
  "violets": "blue",
  "grass": "green",
}
<script src="https://another-origin.com/api"></script> // Browser throws error

// JSON-P
funtion_name({
  "roses": "red",
  "violets": "blue",
  "grass": "green",
})
<script src="https://another-origin.com/api"></script> // Browser considers it as valid script and executes it.
The only requirement is that the origin which is requires this JSONP data must have a pre-defined definition of the funtion "function_name".

WebSockets

The default behaviour of a browser allows any web-socket connection to any origin. Sounds scary, right?

But we have security mechanism in place. Although browsers allows web-scocket connections, they do add an Origin header to the outgoing requests. Now the web-socket server have to validate it against the allowed hosts. In this way we can relax SOP if we want to communicate across origins.


Attacks prevented by Same Origin Policy?

It mitigates threats such as cross-site scripting (XSS). It also prevents malicious website to read data.


Conclusion

Same-Origin-Policy is privacy protection in the world of open Internet connections. If you have appropriate knowledge of methods (we discussed in this article) you can relax this policy as per the need.

Obviously, SOP alone is not sufficient to protect us from the attacks, we need more specialized policies to tackle different attacks. If you want to know about other policies, stay tuned. If you want overview of all the policies please visit browser-policies-part-1-technical-overview-of-browser-policies.


Links & References

  1. https://developer.mozilla.org/en-US/docs/Web/HTTP/Feature_Policy
  2. https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
  3. https://en.wikipedia.org/wiki/Same-origin_policy
  4. https://developer.mozilla.org/en-US/docs/Web/HTTP/Cross-Origin_Resource_Policy_(CORP)

About Author

author
Lakshit Nagar (A full stack enthusiast)
Principle Software Developer
@Oracle India (Ex-ThoughtWorker, IIT Kanpur Alumni)

I love to shape my ideas into a reality. You can find me either working on a project or having a beer with my close friend. :-)

Connect: