跨域方式及其产生的安全问题
字数 1443 2025-08-26 22:11:29
跨域方式及其安全风险详解
一、同源策略基础
1.1 同源定义
同源策略是浏览器最核心的安全功能,满足以下三个条件才属于同源:
- 同协议:如https与http不同源
- 同端口:如默认80端口与8080端口不同源
- 同域名:如aaa.org与bbb.org不同源
例外情况:
- IE浏览器不将端口号纳入同源策略
- 带有src/href属性的标签(
<a>,<script>, ``,<video>,<link>)允许跨域加载资源
1.2 同源策略限制
- 请求交互限制:XMLHttpRequest或fetch请求受同源策略约束
- JS交互限制:不同源的iframe和window.open窗口间不能进行JS交互
二、跨域数据传输方式
2.1 document.domain
适用场景:解决不同窗口间的同源限制,仅适用于顶级域名相同、子域名不同的情况
实现方式:
// 子域页面
document.domain = "parent.com";
安全注意事项:
- 只能设置为当前域或其父域
- 设置后端口号会被重写为NULL,父域也必须设置才能通信
- 不影响XMLHttpRequest/fetch的同源策略
- 子域XSS可能威胁父域及其他设置了document.domain的子域
2.2 window.name
特性:
- 窗口生命周期内所有页面共享同一个window.name
- 不受同源策略限制
- 容量约2MB(浏览器相关)
安全风险:
- 敏感数据不应存储在window.name中
- 任何页面都能读取前页设置的window.name
2.3 location.hash
原理:利用URL锚部分(#)传递数据,改变hash不会导致页面刷新
实现步骤:
- 页面A通过iframe加载页面B,附加hash数据
- 页面B读取location.hash获取数据
- 页面B再通过iframe加载页面A的同源页面C传递数据
2.4 postMessage
安全跨源通信方法:
// 发送方
targetWindow.postMessage(message, targetOrigin);
// 接收方
window.addEventListener('message', function(e) {
if(e.origin !== 'https://trusted.com') return;
// 处理消息
});
安全风险:
- 未验证origin导致XSS:
// 错误示例 - 无origin验证
window.addEventListener('message', function(e){
document.getElementById('name').innerHTML = e.data;
})
- 正则验证不严格:
// 错误的正则验证(缺少$结尾)
if(/^http:\/\/.*evoa\.me/.test(e.origin))
// 可被aaaevoa.me绕过
2.5 JSONP
原理:利用<script>标签跨域特性,通过回调函数获取数据
基本实现:
<script>
function callback(data) { console.log(data); }
</script>
<script src="http://api.com/data?callback=callback"></script>
服务端响应:
callback(["data1","data2"]);
安全风险:
- 敏感数据泄露:
// 恶意页面获取敏感数据
function stealData(data) {
alert("Stolen: " + JSON.stringify(data));
}
- XSS漏洞:
- 未设置Content-Type为application/javascript
- IE浏览器在特定Content-Type下仍可能XSS
防御措施:
- 严格验证Referer
- 使用CSRF Token
- 过滤回调函数名中的特殊字符
2.6 CORS
标准跨域解决方案:
基本头设置:
header("Access-Control-Allow-Origin: http://trusted.com");
带凭证请求:
header("Access-Control-Allow-Origin: http://trusted.com");
header("Access-Control-Allow-Credentials: true");
安全注意事项:
- 使用
*通配符时不能携带cookie - 正则验证不严格导致漏洞:
// 错误的正则(缺少$结尾)
if(preg_match("/^http:evoa.me/", $_SERVER['HTTP_ORIGIN'])) {
header("Access-Control-Allow-Origin: ".$_SERVER['HTTP_ORIGIN']);
}
// 可被http://evoa.me.evil.com绕过
三、安全建议
-
严格验证来源:
- postMessage必须验证event.origin
- JSONP验证Referer和Token
- CORS精确指定允许的域名
-
避免敏感数据暴露:
- 不在window.name中存储敏感信息
- JSONP接口不返回敏感数据
-
正确设置响应头:
- JSONP必须设置Content-Type: application/javascript
- CORS精确控制Access-Control-Allow-Origin
-
输入过滤:
- 过滤JSONP回调函数名中的特殊字符
- 避免动态拼接JS代码
-
使用现代安全方案:
- 优先使用CORS而非JSONP
- 考虑使用OAuth等专业认证方案
通过正确理解和实施这些跨域方法及其安全措施,可以在实现功能需求的同时保障应用安全性。