浏览器同源策略(Same-Origin Policy,SOP)是现代Web安全的基石。它限制了来自不同源的文档或脚本对当前文档属性的读取和操作。简单说,协议、域名、端口三者完全一致才算同源。如果没有SOP,你打开的任何网站都能通过脚本直接读取你邮箱里的内容、窃取你的网银Cookie,甚至冒充你发帖。但这个看似坚固的壁垒,在实现过程中却布满了裂缝。基于同源策略绕过漏洞的浏览器安全研究,本质上就是在寻找这些裂缝,并利用它们打破沙盒的束缚。

很多人以为SOP是铁板一块,实际上它由浏览器中数十个模块协同执行。DOM访问、XMLHttpRequest、Cookie读写、跨窗口通信、插件交互,每个环节都有自己的一套检查规则。规则越复杂,出错的概率就越大。攻击者不需要正面攻破整个策略,只需要找到某个特定场景下检查逻辑的缺失或错误,就能实现绕过。这种绕过往往悄无声息,因为它利用的是浏览器自身的合规行为,而非传统的内存破坏漏洞。

document.domain的降域攻击与隐性风险

document.domain是SOP最经典的例外机制,也是被滥用最严重的功能。它的本意是允许同一公司不同子域名页面之间互相通信。例如,a.example.com和b.example.com都可以将各自的document.domain设置为“example.com”,之后它们就处于同源状态,可以互相访问DOM。问题在于,这种设置是单向不可逆的,而且一旦设置,该页面的源就永久性地变成了根域。

如果一个子域名存在XSS漏洞,攻击者注入脚本将document.domain设置为根域,他就可以跨越子域边界去攻击其他已经设置了相同根域的子域页面。更隐蔽的利用场景是结合第三方服务。很多SaaS平台会为客户分配子域名,如果平台允许用户自定义页面内容,并且没有做好隔离,一个恶意租户就能通过降域手段攻击同属一个根域下的其他租户。修复这个问题的根本方法不是禁用document.domain,而是推动跨域通信全面转向postMessage机制,并在服务端严格隔离不同租户的源。

postMessage滥用与源校验缺失

postMessage是HTML5引入的跨文档通信API,它允许来自不同源的窗口之间安全地传递数据。它的安全性完全依赖于接收端对MessageEvent对象的origin属性进行严格校验。但现实中,大量开发者要么根本不校验origin,要么使用正则表达式进行错误匹配,要么直接使用星号通配符。

一个典型的错误校验写法如下:

window.addEventListener('message', function(e) {
    if (e.origin.indexOf('example.com') !== -1) {
        // 处理敏感数据
    }
});

这种校验方式可以被“example.com.attacker.com”这样的域名轻松绕过。更严重的是,如果接收到的消息被用于执行DOM操作,比如innerHTML赋值,就会导致基于postMessage的XSS。攻击者可以通过iframe加载目标页面,然后使用postMessage向其发送恶意载荷,如果目标页面没有校验发送源,或者校验逻辑有缺陷,载荷就会被执行。这种攻击完全在浏览器内部完成,不经过服务端,传统WAF很难察觉。

跨源资源共享(CORS)的配置陷阱

CORS机制允许服务器通过HTTP头声明哪些外部源可以访问自己的资源。它是对SOP的受控放松。但CORS的配置错误已经成为大规模数据泄露的主要源头。Access-Control-Allow-Origin头部如果被设置为null,问题会非常严重。因为null源在浏览器中代表不透明的源,比如从本地文件系统打开的页面、通过sandbox属性创建的iframe、或者通过data:URL生成的文档,它们的源都是null。

攻击者可以利用这一点,在sandboxed iframe中构造恶意页面,诱导用户点击后发起跨域请求。如果目标服务器的CORS策略允许null源,并且还设置了Access-Control-Allow-Credentials: true,那么攻击者就能带着用户的身份凭证读取敏感数据。另一个常见错误是服务器动态反射Origin头部,而不做白名单校验。开发者为了省事,直接读取请求中的Origin头并原样返回,这等于向所有域开放了权限。正确的做法是维护严格的白名单,逐字匹配,拒绝任何非预期的Origin值。

WebSocket的源绕过与协议混淆

WebSocket协议在握手阶段会发送Origin头,服务端可以据此决定是否接受连接。但WebSocket并没有被SOP严格约束,浏览器只负责发送Origin头,是否接受连接完全由服务端决定。如果服务端忽略了Origin检查,任何网页都可以通过WebSocket连接到该服务,读取实时推送的数据。这在对实时性要求高的金融、协作类应用中尤为危险。

更高级的攻击手法是协议混淆。攻击者构造一个恶意网页,通过WebSocket向目标服务发送经过精心设计的HTTP请求。如果目标网络中存在反向代理或缓存服务器,这些设备可能会将WebSocket流量误解析为普通HTTP请求,从而造成缓存投毒。这种攻击将Web层的漏洞与浏览器跨域特性结合,影响范围远超单一应用。

浏览器扩展的特权滥用与SOP绕过

浏览器扩展通常拥有远超普通网页的权限。很多扩展会在所有页面中注入内容脚本,这些脚本运行在页面自身的源中,但又可以通过扩展后台与更广泛的API通信。如果扩展的内容脚本存在漏洞,或者与页面脚本之间的消息传递没有做好边界隔离,普通网页就可能通过扩展间接获取跨域数据。

一个经典场景是密码管理器扩展。它们会自动填充登录表单,但填充逻辑如果不够严谨,恶意网页可以伪造一个隐藏的登录表单,诱骗扩展填入其他域名的保存密码。因为填充动作发生在当前页面,攻击者通过DOM监听就能窃取到这些凭据。这种攻击绕过了SOP,因为数据是从扩展的特权上下文泄露到了普通网页上下文。扩展开发者必须严格校验消息来源,并避免在页面上下文中直接操作敏感数据。

XS-Leaks:利用侧信道绕过SOP读取信息

XS-Leaks是一类不直接违反SOP,却能达到跨域信息泄露目的的攻击技术。它利用浏览器在各种网络状态、缓存行为、渲染差异上的侧信道,推断出其他源页面的用户状态。例如,利用CSS的:visited伪类曾经可以探测用户访问过的链接历史,虽然现在浏览器已经限制了这一特性,但新的侧信道不断涌现。

基于缓存时间的探测是典型手法。攻击者可以跨域请求目标网站的一张图片或脚本,通过测量资源加载时间来判断该资源是否已被浏览器缓存。如果加载极快,说明用户之前访问过该资源,从而推断出用户的行为或身份。基于帧计数的攻击则利用requestAnimationFrame测量目标iframe的渲染耗时,不同内容的渲染帧率存在细微差异,通过统计分析就能提取出敏感信息。这些技术不需要绕过SOP去直接读取数据,它们只是观察SOP允许的有限交互中泄露出的元信息,但危害同样巨大。

DOM Clobbering与命名属性冲突

DOM Clobbering是一种通过注入HTML元素来覆盖页面JavaScript全局变量的技术。当页面脚本依赖某些全局变量进行安全判断时,攻击者可以在DOM中插入具有特定id或name属性的元素,浏览器会自动将这些元素映射为全局对象的属性。如果安全校验逻辑使用了类似“if (window.originCheck) ”这样的判断,攻击者就可以通过插入一个同名元素来污染这个变量,使其通过校验。

这种攻击在结合跨域场景时尤其危险。假设一个页面通过postMessage接收消息,并使用某个全局对象进行origin白名单校验。如果攻击者能在目标页面中注入HTML(比如通过广告位或UGC内容),他就可以用DOM Clobbering覆盖该校验对象,让恶意消息通过检查。修复方法是避免在全局作用域中依赖变量进行安全判断,改用局部变量或框架提供的安全工具函数,并严格过滤用户可控的HTML内容。

性能API与跨域信息泄露

Performance API提供了丰富的页面加载和资源计时信息。虽然浏览器对跨域资源的详细计时信息做了限制,但攻击者仍然可以通过PerformanceObserver观察到资源加载的持续时间、是否存在连接复用等粗粒度信息。这些信息足以构建出用户的网络环境画像,甚至推断出用户在企业内网中的角色。

更精密的攻击利用Service Worker拦截和测量请求。Service Worker可以捕获页面发出的所有请求,包括跨域请求。虽然它无法读取响应的内容,但可以精确测量请求的耗时、观察响应状态码。通过向内部系统接口发起大量探测请求,攻击者可以绘制出内网拓扑结构,识别存活主机和开放服务。这种攻击将浏览器变成了端口扫描器,而这一切都在SOP的允许范围内,因为Service Worker有权管理其作用域下所有页面的网络请求。

防御思路与架构级解决方案

修复单一漏洞永远跟不上新绕过方法的发现速度。有效的防御必须建立在正确的架构设计之上。首先,彻底放弃依赖document.domain进行跨域通信,全面迁移至postMessage并配合严格、精确的origin白名单校验。其次,CORS策略应该遵循最小权限原则,绝不使用通配符或反射Origin,对于需要携带凭证的请求,必须明确指定允许的具体源。

在应用层面,建议采用CSRF Token与自定义请求头双重校验机制,确保敏感操作请求确实来自可信的页面交互。对于WebSocket连接,服务端必须强制验证Origin头,并实施连接级别的权限控制。内容安全策略(CSP)可以大幅降低XSS被利用后的影响范围,配合frame-ancestors指令防止页面被恶意嵌入iframe。最后,考虑部署跨域隔离策略,如COOP、COEP、CORP等新标准,从浏览器进程模型层面限制跨域交互的能力。这些措施组合起来,能够将SOP绕过漏洞的利用难度提升数个量级,使攻击者难以找到可用的攻击链。