Same-origin policy and cross-domain security
Basic Concepts of Same-Origin Policy
The Same-Origin Policy (SOP) is a critical security mechanism implemented by browsers that restricts how documents or scripts from one origin can interact with resources from another origin. "Same origin" means the protocol, domain, and port must be identical. For example:
https://example.com/page1
andhttps://example.com/page2
are same-originhttps://example.com
andhttp://example.com
are not same-origin (different protocols)https://example.com
andhttps://sub.example.com
are not same-origin (different domains)https://example.com
andhttps://example.com:8080
are not same-origin (different ports)
The Same-Origin Policy primarily affects the following operations:
- AJAX requests
- Web Storage and IndexedDB access
- Cookie reading
- DOM access (iframe communication)
// Attempting cross-origin access triggers SOP restrictions
fetch('https://api.other-site.com/data')
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Cross-origin request blocked:', error));
Cross-Origin Resource Sharing (CORS)
CORS is a standard mechanism supported by modern browsers that allows servers to declare which external origins can access their resources. When a cross-origin request is made, the browser automatically sends a preflight request (OPTIONS) to check if the server permits the actual request.
Simple Requests vs. Preflight Requests
A simple request must meet the following conditions:
- Uses GET, HEAD, or POST methods
- Contains only safe headers (Accept, Accept-Language, etc.)
- Content-Type is application/x-www-form-urlencoded, multipart/form-data, or text/plain
// Simple request example
fetch('https://api.example.com/data', {
method: 'GET',
headers: {
'Content-Type': 'text/plain'
}
});
Non-simple requests trigger a preflight:
// Request that triggers a preflight
fetch('https://api.example.com/data', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'X-Custom-Header': 'value'
},
body: JSON.stringify({key: 'value'})
});
Server-Side CORS Configuration
Node.js Express example:
const express = require('express');
const app = express();
// Basic CORS configuration
app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', 'https://trusted-site.com');
res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
res.header('Access-Control-Allow-Credentials', 'true');
// Handle preflight requests
if (req.method === 'OPTIONS') {
return res.sendStatus(200);
}
next();
});
JSONP Cross-Origin Technique
Before CORS, JSONP was a common cross-origin solution. It leverages the fact that <script>
tags are not restricted by the Same-Origin Policy.
function handleResponse(data) {
console.log('Received data:', data);
}
// Dynamically create a script tag
const script = document.createElement('script');
script.src = 'https://api.example.com/data?callback=handleResponse';
document.body.appendChild(script);
The server must return JSON data wrapped in the callback function:
// Server response
handleResponse({
"name": "Example data",
"value": 42
});
Limitations of JSONP:
- Only supports GET requests
- Lacks error handling
- Security risks (XSS vulnerabilities)
postMessage Cross-Document Communication
For communication between iframes or windows of different origins, the postMessage API can be used.
// Send message to iframe
const iframe = document.getElementById('my-iframe');
iframe.contentWindow.postMessage({
type: 'data_update',
payload: { key: 'value' }
}, 'https://target-origin.com');
// Receive messages
window.addEventListener('message', (event) => {
// Verify origin
if (event.origin !== 'https://trusted-origin.com') return;
console.log('Received message:', event.data);
});
Cross-Origin Security Best Practices
-
Strict CORS Headers:
- Avoid
Access-Control-Allow-Origin: *
- Explicitly specify allowed methods and headers
- Avoid
-
CSRF Protection:
- Use SameSite Cookie attribute
- Implement CSRF tokens
<!-- Form with CSRF token -->
<form action="/transfer" method="POST">
<input type="hidden" name="_csrf" value="token-value">
<!-- Other form fields -->
</form>
- Content Security Policy (CSP):
- Restrict script sources
- Prevent XSS attacks
<meta http-equiv="Content-Security-Policy"
content="default-src 'self'; script-src 'self' https://trusted-cdn.com">
- Avoid Exposing Sensitive Information:
- Do not hardcode API keys in frontend code
- Use environment variables or backend proxies
WebSocket Cross-Origin Security
The WebSocket protocol itself is not restricted by the Same-Origin Policy, but security considerations remain:
const socket = new WebSocket('wss://api.example.com/ws');
// Server should validate Origin header
socket.onopen = () => {
socket.send(JSON.stringify({ action: 'subscribe' }));
};
socket.onmessage = (event) => {
console.log('Received message:', event.data);
};
Modern Cross-Origin Techniques
- Proxy Server:
- Frontend requests same-origin server
- Server forwards requests to target API
// Frontend request
fetch('/api/proxy', {
method: 'POST',
body: JSON.stringify({
url: 'https://target-api.com/endpoint',
method: 'GET'
})
});
- Reverse Proxy:
- Configure with Nginx
location /api/ {
proxy_pass https://target-api.com/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
- CORS Extensions:
- Cross-Origin Resource Policy (CORP)
- Cross-Origin Isolation State
Cross-Origin-Resource-Policy: same-site
Common Cross-Origin Scenarios and Solutions
- Cross-Origin Cookies:
- Set
withCredentials
andAccess-Control-Allow-Credentials
- Set
fetch('https://api.example.com/auth', {
credentials: 'include'
});
- Cross-Origin Images:
- Use
crossOrigin
attribute
- Use
<img src="https://other-site.com/image.jpg" crossOrigin="anonymous">
- Cross-Origin Fonts:
- Configure proper CORS headers
@font-face {
font-family: 'CustomFont';
src: url('https://other-site.com/font.woff2') format('woff2');
font-display: swap;
}
Browser Security Sandbox and Cross-Origin
Modern browsers implement strict sandboxing mechanisms to further enhance cross-origin security:
-
Site Isolation:
- Each site runs in a separate process
- Prevents side-channel attacks like Spectre
-
Cross-Origin Policy Files:
crossorigin.xml
defines allowed cross-origin access- Legacy from Flash era, less used in modern web
-
CORB (Cross-Origin Read Blocking):
- Browser blocks certain types of cross-origin responses
- Sensitive data types like JSON, HTML, XML
Performance Optimization and Cross-Origin
Cross-origin requests can impact performance. Optimization strategies include:
-
Preloading:
<link rel="preconnect" href="https://api.example.com"> <link rel="dns-prefetch" href="https://cdn.example.com">
-
CDN Acceleration:
- Use the same CDN domain for static resources
- Reduce DNS lookups and TCP handshakes
-
HTTP/2 Optimization:
- Multiplexing reduces connection overhead
- Header compression minimizes transmission size
Emerging Standards and Future Trends
-
WebAssembly Cross-Origin:
- Strict module security restrictions
- Requires CORS and CORB protection
-
Portals API:
- Allows embedding cross-origin content
- Provides better user experience
-
SharedArrayBuffer:
- Requires cross-origin isolation state
- High-precision timer restrictions
// Check cross-origin isolation state
if (crossOriginIsolated) {
// Can use advanced features like SharedArrayBuffer
const buffer = new SharedArrayBuffer(1024);
}
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn