Same-origin Policy
The Same‑Origin Policy (SOP) is the first line of defense in modern browsers. It defines a strict boundary that prevents scripts loaded from one web origin from accessing resources belonging to another. By enforcing this rule, browsers protect users from malicious sites that might try to read sensitive data such as cookies, local storage, or the contents of a page they do not own.
What Makes Two URLs the Same Origin?
Two URLs are considered the same origin only when all three of the following components match exactly:
| Component | Description |
|---|---|
| Protocol | The scheme (http, https, ftp, etc.) |
| Domain | The host name or IP address |
| Port | The network port number (default ports are implied if omitted) |
If any one of these differs, the URLs are treated as cross‑origin. The path portion of the URL is irrelevant; /home and /about are still the same origin if the protocol, domain, and port are identical.
Example
https://www.example.com/page.htmlandhttps://www.example.com/other.htmlare same‑origin.http://www.example.com/other.htmlis cross‑origin because the protocol differs.https://api.example.com/datais cross‑origin due to a different domain.https://www.example.com:8080/apiis cross‑origin because the port is different.
What the Policy Restricts
When a script runs in a browser, it is automatically confined to its origin. Without explicit permission, the following cross‑origin actions are blocked:
- DOM Access – Scripts cannot read or manipulate the Document Object Model of a page loaded from another origin, even if it is embedded via an
<iframe>. - Storage Access – Cookies,
localStorage,sessionStorage, and IndexedDB data belonging to a different origin are inaccessible. - Response Reading – While a browser will allow a cross‑origin request to be sent (e.g., via
fetchorXMLHttpRequest), the response body is opaque to the calling script unless the server explicitly grants permission.
It is important to note that SOP does not block the sending of requests. It only blocks the reading of responses. Resources such as images, scripts, and stylesheets are still fetched from other origins; this is why techniques like JSONP were historically viable.
Why SOP Matters
Consider a scenario where a user is logged into their banking site. The browser stores a session cookie that authenticates the user. If a malicious site could freely read responses from the bank’s domain, it could impersonate the user, check balances, or initiate transfers. SOP stops the malicious script from accessing the bank’s data, thereby preventing such credential‑stealing attacks.
In essence, SOP enforces a trust boundary around each origin, ensuring that only code from the same origin can interact with its resources. This boundary is the foundation upon which many other security mechanisms are built.
Legitimate Ways to Communicate Across Origins
In modern web development, cross‑origin interactions are common: front‑end applications often consume APIs hosted on different domains, or embed third‑party widgets. Several standardized methods allow developers to bypass SOP safely:
1. Cross‑Origin Resource Sharing (CORS)
CORS is the de‑facto standard for cross‑origin requests. The server includes specific HTTP headers to declare which origins are allowed to read its responses:
Access-Control-Allow-Origin: https://www.example.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Credentials: true
When a browser sees these headers, it lifts the SOP restriction for that response. For “non‑simple” requests—those that use methods other than GET/HEAD/POST, or that include custom headers—the browser first sends an OPTIONS preflight request to verify permissions.
2. JSONP (Legacy)
JSONP exploits the fact that <script> tags are exempt from SOP. The server returns JavaScript code that calls a callback function supplied by the client. Because only GET requests are possible, JSONP is limited and carries security risks. Modern developers prefer CORS, but JSONP may still be encountered in legacy systems.
3. postMessage
For communication between windows or frames that originate from different domains, the Window.postMessage API provides a secure channel:
// Parent page sends a message to an iframe
iframe.contentWindow.postMessage('hello', 'https://child.example.com');
// Child iframe receives the message
window.addEventListener('message', event => {
if (event.origin !== 'https://parent.example.com') return;
console.log(event.data);
});
postMessage allows arbitrary data to be exchanged while still enforcing origin checks, making it ideal for cross‑origin messaging.
4. Server‑Side Proxy
A common pattern is to route all external requests through a server that shares the same origin as the front end. The browser talks to the proxy, which then forwards the request to the target API. Because the proxy is on the same origin, SOP is never triggered. This approach also gives developers full control over request headers, authentication, and caching.
Summary
The Same‑Origin Policy is a cornerstone of web security, defined by the trio of protocol, domain, and port. It blocks scripts from reading or manipulating data across origins, thereby preventing a wide range of attacks such as credential theft and data exfiltration. While SOP is restrictive, it can be safely circumvented using standardized techniques like CORS, postMessage, and server‑side proxies. Mastery of these tools is essential for any web developer working in today’s distributed, API‑driven ecosystem.