本文目录导读:

同源策略(Same-Origin Policy, SOP)是浏览器最核心的安全机制之一,对于防范CSRF(跨站请求伪造),同源策略不能直接阻止请求的发送,但从根本上限制了攻击者读取响应(获取数据)的能力,从而破坏了CSRF升级为信息泄露或账户劫持的关键链条。
为了帮助你清晰理解,这里需要先澄清一个常见的误区:同源策略并不能阻止CSRF攻击本身。
根本原因:CSRF利用了SOP的“漏洞”
在标准的CSRF攻击中,攻击者诱导受害者浏览器向目标网站(如银行网站 bank.com)发送请求(如转账)。
- 攻击成功的原因:浏览器在执行
<img>、<form>、<script>等标签发起的跨域请求时,会无条件地自动携带目标网站的Cookie(同源策略允许这个行为),只要受害者登录过bank.com,这个请求就是“已验证”的。 - SOP在这里做了什么:SOP允许这个跨域请求被发送出去(浏览器不会阻止发请求),SOP只阻止页面读取
bank.com返回的响应内容。
SOP允许攻击者触发请求,这是CSRF能成功的前提,依赖SOP来防CSRF是行不通的。
SOP如何“间接”防范更高级的CSRF
虽然SOP无法阻止请求的发送,但它通过限制读取响应,在以下场景中起到了关键的防御或降级作用:
场景A:防御“读取型CSRF”(利用XSSI)
这是一种更隐蔽的CSRF,攻击者不仅想让受害者执行操作,还想窃取数据。
- 攻击链条:攻击者想通过CSRF获取用户的敏感数据(如
bank.com/api/user_info)。 - SOP的防范:如果攻击者在恶意页面上通过
<script>标签或fetch发起跨域请求,浏览器会阻止恶意页面读取返回的JSON或HTML数据,攻击者无法获取到用户的余额、手机号等信息。 - 例外:如果返回的数据恰好是合法的JavaScript代码(例如某些JSONP接口),则可能通过
script标签注入,但现代网站已禁用JSONP。
SOP阻止攻击者“看到”CSRF请求的响应,从而避免了CSRF被用于数据窃取。
场景B:防御“登录态劫持”(配合SameSite Cookie)
现代浏览器引入了 SameSite Cookie属性,这是对SOP的重要补充,专门解决SOP无法阻止发送Cookie的问题。
- SOP + SameSite=Lax:当浏览器判断一个请求是“跨站请求”(即不是由
bank.com自身页面触发的)时,会不携带bank.com的Cookie,这直接切断了CSRF攻击的燃料——身份凭证。 - 作用机制:SameSite属性是SOP策略的“Cookie层面”延伸,它告诉浏览器:“只有同源请求才允许带我的Cookie”。
同源策略的局限性(为什么不能全靠它)
| 场景 | SOP能否阻止CSRF请求发送? | SOP能否阻止读取响应? | 实际风险 |
|---|---|---|---|
| 表单提交 (POST) | 不能(允许发送) | 不能(浏览器不阻止,但页面无法读取) | 高危:转账、改密等操作可被触发 |
| 图片/脚本加载 (GET) | 不能(允许发送) | 不能(浏览器不阻止) | 高危:利用GET接口操作(如删除) |
| Fetch/XMLHttpRequest | 规则复杂:默认不允许跨域,但可配置CORS | 严格:默认完全禁止跨域读取 | 低危:攻击者难以通过JS发起跨域请求 |
| 嵌入第三方内容 (iframe) | 不涉及 | 受限(无法读取iframe内容) | 低危 |
同源策略的真正角色
同源策略是CSRF防御的“最后一道防线”,但不是“主防线”。
- 主防线:必须依赖服务端验证,如:
- CSRF Token(最常用)
- Referer/Origin 头验证
- 二次身份验证(如输入支付密码)
- SOP的贡献:
- 防止数据被窃取:阻止攻击者读取CSRF请求的结果。
- 配合SameSite Cookie:现代浏览器通过
SameSite=Lax/Strict直接解决了“携带Cookie”这一核心问题(前提是用户使用现代浏览器)。 - 限制自定义请求头:攻击者无法通过简单的
<img>或<form>添加X-Requested-With: XMLHttpRequest等自定义头,而服务器可以检查这个头是否存在(这是一种额外的防御手段,虽非SOP直接强制的,但SOP限制了攻击者的手段)。
核心一句话总结
同源策略无法阻止CSRF请求被发送(因为浏览器允许跨域发请求并带Cookie),但它能阻止攻击者读取CSRF请求返回的数据,从而防止CSRF从“操作型攻击”升级为“数据窃取型攻击”。 现代CSRF防御主要依赖服务端的验证(如CSRF Token)和浏览器的 SameSite Cookie 策略。