Same-Origin Policy: Browser Security Basics

The same-origin policy restricts scripts on one origin from accessing resources on a different origin.

Same-Origin Policy

The same-origin policy is the foundational browser security rule that keeps websites isolated from one another. Without it, any malicious website could silently read your banking data, steal session cookies, or interact with any other tab you have open in your browser.

What Is the Same-Origin Policy

The same-origin policy (SOP) is a browser security mechanism that prevents JavaScript running on one origin from reading resources belonging to a different origin. An origin is defined by three components: the protocol (also called the scheme), the domain, and the port number. All three must match exactly for two URLs to be considered the same origin.

This rule was introduced to address a fundamental problem with how browsers work. When you visit a website, the JavaScript on that page runs inside your browser with access to the browser's storage, cookies, and the ability to make network requests. Without the same-origin policy, a script on any website could issue requests to your bank, your email provider, or any other service you are logged into, and read the responses. The same-origin policy closes that gap by restricting what JavaScript can read across different origins.

Compared to https://techyall.com Same Origin? Reason
https://techyall.com/tutorialYesSame scheme, domain, and port (implicit 443)
http://techyall.comNoDifferent scheme (http vs https)
https://api.techyall.comNoDifferent subdomain counts as a different origin
https://techyall.com:8080NoDifferent port (443 vs 8080)
https://google.comNoEntirely different domain

A common point of confusion is that subdomains are not treated as the same origin. Even if api.example.com and www.example.com clearly belong to the same company, the browser treats them as separate origins by default. Similarly, switching from HTTP to HTTPS changes the scheme and therefore changes the origin, even if the domain and port are identical.

What the Same-Origin Policy Blocks

The same-origin policy restricts JavaScript from reading data that comes from a different origin. Specifically, JavaScript running on origin A cannot do the following when interacting with origin B:

  • Read the DOM of a page loaded inside an iframe from a different origin
  • Read the body of an HTTP response returned by a cross-origin fetch or XMLHttpRequest request
  • Access cookies, localStorage, or sessionStorage belonging to a different origin
  • Read response headers from a cross-origin request unless the server explicitly allows it through CORS headers

It is important to understand that the same-origin policy restricts reading, not sending. A browser will generally allow JavaScript to send a request to a different origin. The restriction is on what the JavaScript can do with the response it gets back. This distinction matters and is something developers often misunderstand when debugging cross-origin issues.

What the Same-Origin Policy Allows

Despite being a security boundary, the same-origin policy does not block all cross-origin activity. Several types of cross-origin interactions are permitted by default, because blocking them entirely would break the basic way the web works.

  • Embedding images, scripts, stylesheets, audio, and video from other origins is allowed. The browser loads them, but JavaScript cannot inspect their contents.
  • Loading a page from another origin inside an <iframe> is allowed. JavaScript cannot read the iframe's DOM or intercept its responses.
  • Submitting HTML forms to cross-origin URLs is allowed. Traditional form posts have always worked this way.
  • Navigating the browser to a cross-origin URL is allowed. Clicking a link and going to a different site is normal behavior.
  • Cross-origin requests are allowed when the destination server grants explicit permission through CORS response headers.

This distinction between loading and reading is at the heart of how the same-origin policy operates. Embedding a YouTube video in your page is fine. Reading the content inside that YouTube iframe with JavaScript is not. The browser fetches the resource but keeps it isolated from scripts on your page.

Same-Origin Policy vs CORS

CORS (Cross-Origin Resource Sharing) is often discussed alongside the same-origin policy, and the two are closely related but serve different roles. The same-origin policy is the restriction. CORS is the mechanism that allows servers to selectively lift that restriction for specific trusted origins.

When a browser makes a cross-origin request, it checks the response headers to see whether the server has granted access. If the server returns an Access-Control-Allow-Origin header that matches the requesting origin (or uses a wildcard), the browser allows JavaScript to read the response. Without that header, the browser blocks access even though the request was sent and received successfully at the network level.

Feature Same-Origin Policy CORS
What it is A browser-enforced restriction on cross-origin reads A mechanism for servers to relax the SOP for specific origins
Who controls it The browser The server, through response headers
Default behaviour Block cross-origin reads from JavaScript No CORS headers means no cross-origin JavaScript access
Effect on POST requests POST can be sent, but the response cannot be read by JS CORS headers allow JavaScript to read the response
Applies to All browsers, all origins Only origins the server explicitly permits

One key point is that CORS does not bypass the same-origin policy. It works within it. The browser still enforces the same-origin policy. The server simply tells the browser which origins are trusted and therefore allowed to read the response. If no CORS headers are present, the policy remains fully in effect.

Why Subdomains Are Treated as Different Origins

Many developers are surprised to find that app.example.com and api.example.com cannot share cookies or read each other's responses without CORS. This is intentional. If subdomains were automatically trusted, a compromised subdomain could read data from any other subdomain on the same parent domain.

There is a mechanism called document.domain that used to allow two pages on different subdomains of the same parent domain to opt into sharing access, but this approach has been deprecated in modern browsers due to security concerns. The recommended solution today is to use CORS headers or, for cookie sharing, set the cookie domain attribute to the shared parent domain.

The Same-Origin Policy and iframes

iframes present a specific use case worth understanding. When a page on example.com embeds an iframe pointing to bank.com, the browser loads the bank page inside the frame. However, JavaScript on example.com cannot read the contents of that iframe. It cannot inspect the DOM, read form values, or intercept any data displayed inside the frame.

This is exactly why payment processors and authentication flows often use iframes hosted on their own domain. The parent page can embed the iframe without ever having access to the sensitive data entered inside it. The data is submitted directly from the iframe to the payment provider's servers, keeping it isolated from the host page entirely.

Frequently Asked Questions

  1. Does the same-origin policy apply to server-to-server requests?
    No. The same-origin policy is enforced only by browsers. When a server makes a request to another server using tools like curl, Node.js fetch, or any backend HTTP client, the same-origin policy does not apply. It is purely a browser mechanism designed to protect users from malicious scripts running in web pages.
  2. What is CSRF and does the same-origin policy protect against it?
    CSRF (Cross-Site Request Forgery) is an attack where a malicious site tricks a user's browser into sending a request to another site where the user is already logged in. The same-origin policy offers partial protection because JavaScript on the attacker's page cannot read the response from the target site. However, the request itself can still be sent and processed. CSRF tokens and the SameSite cookie attribute are the proper defences against this attack.
  3. Why can I embed a YouTube video but not read its content with JavaScript?
    The same-origin policy allows embedding iframes from other origins. The browser loads and renders the content inside the frame. What it does not allow is JavaScript on the parent page reading the iframe's DOM, accessing its cookies, or intercepting its network responses. Loading and reading are treated as two separate operations with different rules.
  4. Can I disable the same-origin policy for development?
    Some browsers can be launched with flags that disable certain security checks for development purposes, but this is strongly discouraged. A much safer approach is to configure CORS headers correctly on your development server, or use a local proxy to route requests through the same origin as your frontend. Disabling the same-origin policy exposes your browser to real security risks even during local development.
  5. Does the same-origin policy apply to WebSockets?
    WebSocket connections are not directly covered by the same-origin policy in the same way as HTTP requests. Browsers do send an Origin header in the WebSocket handshake, but it is up to the server to check and enforce that value. This means WebSocket servers need to validate the Origin header themselves to prevent unauthorized cross-origin connections.

Conclusion

The same-origin policy is the rule that keeps websites isolated from each other inside the browser. It prevents JavaScript on one origin from reading data that belongs to another, protecting users from a wide range of attacks that would otherwise be trivially easy to carry out. Understanding what it blocks, what it allows, and how it differs from CORS is essential for anyone building or securing web applications. CORS is the controlled way to selectively relax these restrictions when two origins genuinely need to share data. Together, they form the foundation of how the browser enforces boundaries between the sites you visit. To go deeper, explore CORS, XSS, and HTTP security headers.