利用CORS(跨域资源共享)配置不当的三种攻击手段
同源策略(SOP)限制了网络应用之间的信息共享,仅允许同域内进行数据共享。这是很久以前就定下的浏览器安全防护措施。但是,随着网络世界的快速发展,在很多应用场景下,我们都需要将信息从一个子域传递到另一个子域,又或者需要在不同域之间传递数据。这其中可能涉及非常敏感且重要的功能,例如将访问令牌和session标识符传递给另一个应用。
为了在有SOP的情况下实现跨域通信,开发人员必须使用不同的技术绕过SOP来传递数据。此时,“绕过”既是一个正常的技术问题,又是一个敏感的安全问题。为了在不影响应用安全状态的情况下实现信息共享,HTML5中引入了跨域资源共享(CORS)。但是,很多开发者在使用时没有考虑到其中蕴含安全风险,容易出现配置错误,导致出现安全漏洞。
因此,作为安全人员,了解如何利用错误配置的CORS是非常重要。它可能是整条攻击链的发起点,从简单的数据窃取可发展到对整个应用的破坏。
什么是CORS?
跨域资源共享(CORS)是一种网络机制,使Web浏览器在受控的情况下通过xmlHttpRequest API执行跨域请求。这些跨域请求具有Origin标头,用于标识发起请求的域。它定义了在Web浏览器和服务器之间使用的协议,以确定是否允许跨域请求。
关键的CORS header
有许多与CORS相关的HTTP的header,但以下三个和安全最为相关:
Access-Control-Allow-Origin
指定哪些域可以访问本域的资源。例如,如果requester.com
想要访问provider.com
的资源,那么开发人员可以用此授予requester.com
访问provider.com
资源的权限。
Access-Control-Allow-Credentials
指定浏览器是否将使用请求发送cookie。仅当allow-credentials
标头设置为true
时,才会发送cookie。Access-Control-Allow-Methods
指定可以使用哪些HTTP请求方法(GET,PUT,DELETE等)来访问资源。开发人员可用其进一步加强控制力,增强安全性。
三个攻击场景
1.CORS中header滥用通配符(*):
最常见的CORS配置错误就是错误地使用诸如(*)之类的通配符去规定允许访问本域资源的外来域。 这通常设置为默认值,这意味着任何域都可以访问本域上的资源。例如,以下请求:
GET /api/userinfo.php
Host:www.victim.com
Origin:www.victim.com
当你发送上述请求时,你可以看到具有Access-Control-Allow-Origin
header的响应,如以下所示:
HTTP/1.0 200 OK
Access-Control-Allow-Origin:*
Access-Control-Allow-Credentials:true
从上可以看出,header配置了通配符(*)。这意味着任何域都可以访问本域的资源。
在测试客户的Web应用时,我们往往可以看到这种错误配置。我们能够利用它来获取网站的用户信息,如姓名,用户ID,电子邮件ID等,并将这些信息发送到外部服务器。在下图中,我们将Origin
修改为攻击者所控制的域名。
以下是我们收到的回复。其中Access-Control-Allow-Origin:*
,这意味目标域允许来自其他所有域对其发出的资源请求。我们的Testing.aaa.com
网站也是一样。
我们在https://testing.aaa.com
上放上了漏洞利用代码,可从目标应用程序中窃取敏感数据。当受害者在浏览器中打开https://testing.aaa.com
时,就会自动把受害者在目标域的敏感信息发送给攻击者的服务器。如下图所示。
2.信任域的配置存在缺陷
另一种常见的错误配置是验证可信域名的代码存在缺陷。 例如,以下请求:
GET /api/userinfo.php
Host: provider.com
Origin: requester.com
对以上请求的回应是:
HTTP/1.0 200 OK
Access-Control-Allow-Origin: requester.com
Access-Control-Allow-Credentials: true
开发人员貌似配置了验证Origin header
中URL的代码,白名单只有requester.com
。但是,当攻击者发起的请求如下所示:
GET /api/userinfo.php
Host: example.com
Connection: close
Origin: attackerrequester.com
服务器的响应如下:
HTTP/1.0 200 OK
Access-Control-Allow-Origin: attackerrequester.com
Access-Control-Allow-Credentials: true
发生这种情况的原因是可能的后端配置错误,例如:
if ($_SERVER['HTTP_HOST'] == '*requester.com')
{
//Access data
else{ // unauthorized access}
}
我们在对某个客户的应用进行测试时遇到了这个问题。本域provider.com
只信任域requester.com
结尾的Origin
,包括attackerrequester.com
。因此,我们将Origin
篡改为attackerrequester.com
进行测试。
在上面请求的回应中,相同的attackerrequester.com
出现在 Access-control-Allow-Origin
中,这意味着provider.com
允许将资源发送到任何以requester.com
结尾的域中。
此时,如果要继续攻击,我们可以申请一个以requester.com
结尾的域名,然后放上恶意代码,引诱受害者访问我们的网站。
3.使用XSS实现CORS攻击
开发人员用于对抗CORS攻击的一种防御机制是将一些频繁请求的域列入白名单。但是,这也有缺陷,若白名单中某个域的子域容易受到其他攻击(如XSS)的影响,它也会影响CORS的安全性。
如下示例,以下代码表示允许requester.com
的子域访问provider.com
的资源。
if ($_SERVER['HTTP_HOST'] == '*.requester.com')
{
//Access data
else{ // unauthorized access}
}
假设用户可以访问sub.requester.com
但不能访问requester.com
,再假设sub.requster.com
存在XSS漏洞。用户就可以使用XSS攻击来利用provider.com
。
示例如下,我们在同一个域上托管了两个应用。涉及CORS的应用域名为 testingcors.com
,其他应用托管在pavan.testingcors.com
,而且它存在XSS漏洞。
利用这个存在XSS的子域,我们就可以从testingcors.com
获取敏感信息 。我们在“Name”参数中注入了的javascript的payload。在页面加载成功后,脚本将从testingcors.com
偷取敏感信息。
结论
CORS是OWASP TOP 10的漏洞。在实际利用的过程中,人们经常忽略CORS配置的重要性。作为安全专家,了解此漏洞以及如何利用此漏洞非常重要。
本文由白帽汇整理并翻译,不代表白帽汇任何观点和立场
来源:https://www.we45.com/blog/3-ways-to-exploit-misconfigured-cross-origin-resource-sharing-cors
最新评论