同源策略(SOP)与跨域资源共享(CORS)的进阶应用与安全风险详解
字数 2126 2025-11-19 08:34:37
同源策略(SOP)与跨域资源共享(CORS)的进阶应用与安全风险详解
1. 同源策略(SOP)的核心概念
同源策略是浏览器最基础的安全机制之一,用于限制不同源的文档或脚本之间的交互。
- 同源的定义:协议(Protocol)、域名(Host)、端口(Port)三者完全一致。例如:
https://example.com/app1和https://example.com/app2同源(协议、域名、端口相同)。https://example.com和http://example.com不同源(协议不同)。
- SOP的限制范围:
- Cookie、LocalStorage 和 IndexDB 访问。
- DOM 元素操作(如通过
iframe嵌入跨源页面时无法访问其内容)。 - AJAX 请求默认被浏览器拦截(除非目标服务器明确允许跨源)。
2. 为什么需要跨域资源共享(CORS)?
SOP 虽然安全,但实际业务中常需要合法的跨源访问(例如前端域名 https://ui.example.com 需要调用 API 域名 https://api.example.com)。CORS 是一种基于 HTTP 头部的机制,允许服务器声明哪些外部源可以访问其资源。
3. CORS 的工作机制
3.1 简单请求与非简单请求
- 简单请求(满足以下所有条件):
- 方法为 GET、POST 或 HEAD。
- 请求头仅包含允许的列表(如
Accept、Accept-Language、Content-Language、Content-Type为application/x-www-form-urlencoded、multipart/form-data或text/plain)。
- 浏览器行为:直接发送请求,并在请求头中自动添加
Origin: https://ui.example.com。 - 服务器响应:
- 若允许跨源,返回
Access-Control-Allow-Origin: https://ui.example.com(或*表示允许任意源)。 - 若未返回该头部,浏览器拦截响应。
- 若允许跨源,返回
3.2 非简单请求(需预检请求)
触发条件(满足任一):
- 方法为 PUT、DELETE 或自定义方法(如
PATCH)。 - 包含非常规头部(如
Authorization、Content-Type: application/json)。
流程分两步:
- 预检请求(Preflight Request):
- 浏览器自动发送
OPTIONS请求,头部包含:Origin: https://ui.example.com Access-Control-Request-Method: PUT Access-Control-Request-Headers: Content-Type, Authorization - 服务器响应需包含:
Access-Control-Allow-Origin: https://ui.example.com Access-Control-Allow-Methods: GET, POST, PUT Access-Control-Allow-Headers: Content-Type, Authorization Access-Control-Max-Age: 86400 // 缓存预检结果(秒)
- 浏览器自动发送
- 实际请求:
- 预检通过后,浏览器发送真实请求,流程同简单请求。
4. CORS 的安全风险与配置错误
4.1 常见错误配置
-
滥用
Access-Control-Allow-Origin: *:- 若响应包含敏感信息(如带认证的 API),任意网站均可通过前端代码窃取数据。
- 安全建议:动态校验
Origin头,仅允许可信域名。
-
过度放宽
Access-Control-Allow-Credentials:- 该头部允许跨源请求携带 Cookie(需配合
Allow-Origin为具体域名,不可为*)。 - 风险:若允许任意源携带 Cookie,可能导致 CSRF 攻击升级。
- 该头部允许跨源请求携带 Cookie(需配合
-
未校验
Origin头的来源:- 攻击者可伪造
Origin头欺骗服务器返回Allow-Origin,但浏览器会校验响应头是否匹配请求源。 - 注意:服务器端应拒绝处理非法
Origin的请求,而非仅依赖浏览器限制。
- 攻击者可伪造
-
Access-Control-Allow-Methods包含危险方法:- 例如允许
DELETE方法且未做权限控制,可能导致跨源资源删除。
- 例如允许
4.2 组合攻击案例
- CORS + CSRF:
- 若网站配置
Allow-Credentials: true且Allow-Origin为动态信任,攻击者可诱导用户访问恶意页面,利用跨源请求自动携带 Cookie 调用敏感 API。
- 若网站配置
5. 其他跨域方案与对比
- JSONP(已逐渐淘汰):
- 通过
<script>标签加载跨源资源,但仅支持 GET 请求,且易遭受 XSS 和数据泄露。
- 通过
- 代理服务器:
- 前端请求同源代理,由代理转发至跨源 API(避免浏览器限制)。
- PostMessage API:
- 用于跨源窗口间安全通信,但需双方页面实现消息验证逻辑。
6. 防御最佳实践
- 严格限制
Allow-Origin:使用白名单机制,避免动态信任未经验证的源。 - 最小化
Allow-Methods和Allow-Headers:仅开放必要的方法和头部。 - 敏感接口避免 CORS:对认证 API 优先采用同源部署或代理转发。
- 监控异常跨源请求:日志中记录
Origin头,及时发现恶意源。
通过理解 CORS 的机制与风险,可平衡业务需求与安全性,避免配置错误导致的数据泄露。