Same-Origin Policy (SOP)
What is Same-Origin Policy (SOP)?
Same-Origin Policy (SOP) is a fundamental security mechanism implemented by web browsers that prevents scripts or documents from one origin from interacting with resources from another origin. SOP is the cornerstone of web security, designed to protect users from malicious websites that might attempt to access sensitive data from other sites.
The policy works by restricting how documents or scripts loaded from one origin can interact with resources from another origin. This prevents a wide range of security vulnerabilities, including Cross-Site Scripting (XSS) and Cross-Site Request Forgery (CSRF) attacks.
How Origins Are Defined
An origin is defined by the combination of three components:
- Protocol (Scheme):
http://orhttps:// - Hostname (Domain):
example.com - Port:
:80,:443, or other port numbers
Examples of same vs. different origins:
| URL 1 | URL 2 | Same Origin? | Reason |
|---|---|---|---|
https://example.com | https://example.com | ✅ Yes | Identical protocol, domain, and port |
https://example.com | http://example.com | ❌ No | Different protocol |
https://example.com | https://sub.example.com | ❌ No | Different subdomain |
https://example.com:443 | https://example.com:8080 | ❌ No | Different port |
https://example.com | https://example.org | ❌ No | Different domain |
What SOP Restricts
The Same-Origin Policy restricts several types of cross-origin interactions:
- DOM Access: Scripts cannot access the DOM of documents from different origins
- Cookies: Cookies are only sent to the origin that set them
- AJAX Requests: XMLHttpRequest and Fetch API calls to different origins are blocked
- Storage: localStorage and sessionStorage are isolated by origin
- Web Workers: Workers cannot access resources from different origins
Exceptions to SOP
While SOP is strict, there are several exceptions and mechanisms that allow controlled cross-origin interactions:
- Cross-Origin Resource Sharing (CORS): Allows servers to specify which origins can access their resources
- JSONP (JSON with Padding): Legacy technique for cross-origin data fetching
- Cross-Document Messaging: Secure communication between documents from different origins
- WebSockets: Not subject to SOP when established
- Images, Scripts, and Stylesheets: Can be embedded from different origins
Security Benefits
Prevents data theft:
- Stops malicious websites from reading sensitive data from other sites
- Protects user sessions and authentication tokens
- Prevents unauthorized access to private information
Mitigates attacks:
Enforces isolation:
- Keeps different websites separate
- Prevents interference between web applications
- Maintains user privacy across different services
Common SOP Scenarios
Blocked by SOP:
// Trying to access content from a different origin
fetch('https://api.example.com/data')
.then(response => response.json())
.then(data => console.log(data)); // Blocked by SOP
Allowed by SOP:
// Accessing resources from the same origin
fetch('/api/data')
.then(response => response.json())
.then(data => console.log(data)); // Allowed
Cross-origin embedding (allowed):
<!-- These are allowed by SOP -->
<img src="https://other-site.com/image.jpg" alt="Cross-origin image">
<script src="https://cdn.example.com/library.js"></script>
<link rel="stylesheet" href="https://cdn.example.com/styles.css">
Bypassing SOP (Legitimate Methods)
1. Cross-Origin Resource Sharing (CORS)
Access-Control-Allow-Origin: https://trusted-site.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Credentials: true
2. JSONP (Legacy Method)
// Client-side
function handleResponse(data) {
console.log(data);
}
const script = document.createElement('script');
script.src = 'https://api.example.com/data?callback=handleResponse';
document.body.appendChild(script);
3. Cross-Document Messaging
// Sender
targetWindow.postMessage({ message: 'Hello' }, 'https://target-origin.com');
// Receiver
window.addEventListener('message', (event) => {
if (event.origin !== 'https://sender-origin.com') return;
console.log(event.data);
});
4. WebSockets
// WebSockets are not subject to SOP
const socket = new WebSocket('wss://api.example.com');
socket.onmessage = (event) => {
console.log(event.data);
};
Security Risks and Considerations
Overly permissive CORS:
- Using
Access-Control-Allow-Origin: *can expose sensitive data - Allowing credentials with wildcard origins is dangerous
JSONP vulnerabilities:
- No built-in error handling
- Vulnerable to XSS if callback parameter is not sanitized
- No support for modern security features
Cross-document messaging risks:
- Must validate the origin of incoming messages
- Without origin validation, can be exploited by malicious sites
Subdomain vulnerabilities:
- Different subdomains are considered different origins
- Requires explicit CORS configuration for cross-subdomain access
Best Practices
- Validate all cross-origin interactions - never trust external origins
- Use CORS judiciously - be specific with allowed origins
- Avoid JSONP - use CORS instead for modern applications
- Validate message origins in cross-document messaging
- Use secure cookies with
SameSiteattributes - Implement proper authentication for sensitive operations
- Combine with other security headers:
Example: Secure Cross-Origin Communication
Server-side (Node.js with Express):
app.use((req, res, next) => {
// Only allow specific trusted origins
const allowedOrigins = ['https://trusted-site.com', 'https://partner-site.com'];
const origin = req.headers.origin;
if (allowedOrigins.includes(origin)) {
res.header('Access-Control-Allow-Origin', origin);
res.header('Access-Control-Allow-Credentials', 'true');
}
next();
});
Client-side (Secure Cross-Document Messaging):
// Sender
const targetWindow = document.getElementById('iframe').contentWindow;
targetWindow.postMessage(
{ action: 'update', data: sensitiveData },
'https://trusted-receiver.com'
);
// Receiver
window.addEventListener('message', (event) => {
// Always validate the origin
if (event.origin !== 'https://trusted-sender.com') {
console.warn('Message from untrusted origin:', event.origin);
return;
}
// Process the message
console.log('Received:', event.data);
});
Related Security Concepts
Salt (Cryptography)
Learn about cryptographic salt - random data added to passwords before hashing to prevent attacks like rainbow tables and enhance security.
SAML (Security Assertion Markup Language)
Discover how SAML enables secure single sign-on (SSO) and identity federation across enterprise applications and organizations.
