HTTP CORS攻防指南(上)
2020-11-04 13:00:00 Author: www.4hou.com(查看原文) 阅读量:198 收藏

fanyeee 技术 2020-11-04 12:00:00

收藏

前言

嗨,你们好。希望大家都好。今天,我们将跟大家聊一些Web应用安全方面的话题。

所以,如果您曾经想对HTTP CORS(跨源资源共享)的内部工作原理感到疑惑,或者之前从未听说过它,但又觉得它好像一个重要的Web应用概念,需要进一步了解它的话——恭喜您,您来对地方了。

在接下来的篇章中,我们将深入研究浏览器和服务器是如何处理CORS规则的。我希望通过理论联系实际的方法,使您了解如何安全地配置Web资源以使其值得信任。

总的来说,我们将涵盖以下主题:

· HTTP CORS基础知识,包括简单与预检型HTTP请求、同源策略、CORS标准头部、错误配置等;

· 利用基于Docker的容器化环境,分析应用的源代码,并将其与预期行为进行比较;

· CORS规则如何适用于不同的JavaScript API实现(XHR和Fetch);

· 通过示例场景,理解HTTP请求-响应周期;

· 如何使用手动代理拦截工具绕过受CORS保护的资源;

· 介绍API自动化CORS相关项目和其他有用的信息来源。

同源策略(SOP)

在谈CORS之前,我们必须先了解一下网络资源访问保护的基本概念:同源策略(Same Origin Policy,SOP)。

SOP的概念是由Netscape公司在1995年提出的,目前所有主流的网页浏览器都已经支持SOP[1]

为了避免外部用户在未经授权的情况下使用站内资源,浏览器采用了基于域的限制策略。在形式上,上述外部用户是通过其来源(或者域)来识别的,并通过URL进行访问。

所谓同源策略,简单来说就是来自域A的文档,只允许被来自同一个域中的文档进行访问。实际上,只有当SOP被正确实施时(取决于浏览器的实现),该规则才会奏效。这个策略旨在减少可能的攻击途径。

但让我们来描绘一下上面所说的“域”长啥样。实际上,我们可以把一个域理解为一个元组:

因此,只有两个URL具有相同的元组时,它们才表示相同的源。下面是给定URL,即http://hacking.cors.com/mr_robots.txt的对比情况: 

1.png1.png

给定URL的对比情况

此外,请记住,SOP允许使用GET和POST方法在inter-origin发送HTTP请求,但它禁止在inter-origin使用PUT和DELETE方法。除此之外,只有在inter-origin发送请求的情况下,才允许发送自定义的HTTP头部,对外部则是不允许的[2]

SOP的变体

实际上,目前存在多种类型的同源策略,因为它们往往根据现有的技术,来应用特定的规则。

当前开发的主要SOP策略都是针对DOM(文档对象模型)的访问控制的,也就是一种处理JavaScript和其他脚本语言跨域访问DOM属性和方法的机制。

DOM的访问控制主要基于DOM的属性"document.domain"的状态。但是对于JavaScript的XMLHttpRequest API来说,这种方法是无效的,因为它并没有考虑document.domain属性。现在,我们不要花太多精力在这些细节上面,后面将详细探讨这些话题。

所以,如果我们把SOP作为一个沙盒的概念,那么对其他Web技术也具有同源限制就变得很合理了。这些技术包括Cookie、Java、old-R.I.P Flash,它们也应该具有同源要求。

HTTP CORS基础知识

SOP技术无疑是向更加安全的Web应用程序前进了一大步。但默认情况下,它将应用拒绝规则。

万维网的真正本质是,网页可以与网络上的其他资源进行通信。Web应用就是为了访问外部资源。

那么我们如何放宽同源规则,同时保持受限资源的安全访问呢?你懂的:CORS

简单来说,跨源资源共享允许特定域/源的页面使用另一个域/源的资源。那么,谁有权访问资源呢?这个问题还是资源所有者(服务器)说了算。

浏览器与服务器之间的信任关系是通过CORS HTTP头部[3]建立的。在一般情况下,它们是由资源的Web服务器(如Nginx、Apache、IIS等)、应用程序或浏览器添加到HTTP请求和响应中的。CORS头部则用于指示浏览器是否信任来源,并继续进行响应处理。

在这里我们先喘口气。注意,我们先让浏览器完全信任服务器返回的响应。请记住这一点。

简单型请求(Simple Request)

除了预检型请求之外,还有一种请求类型:简单型请求。所谓简单型请求,就是指符合以下条件的请求:

1.png

简单型请求的组成部分

在发送异步HTTP请求时,我们经常使用XMLHttpRequest[5]或Fetch[6] JavaScript API。

预检型HTTP请求(Preflight HTTP Request)

有时浏览器会发送预检型HTTP请求,以向服务器查询哪些CORS属性是允许访问和受支持的。但是,这并不会改变服务器和浏览器之间的信任关系。

预检型HTTP请求(它采用HTTP OPTIONS请求的形式)会得到一个同样可信的HTTP响应。唯一的区别在于头部信息,它用于指示浏览器如何继续获取预定的跨源资源。

3.jpg

通过api.domain.org删除avatar.org资源的预检流程

上面,我们介绍的是理论部分,下面我们将进入实战部分。

CORS头部

CORS实现同源控制时,通常会用到以下头部:

1.png

CORS头部及相应的HTTP类型

凡是在“Used for Preflight HTTP”一栏中标有YES的头部,都在预检方面起到了至关重要的作用。

其中,有些头部用于表示允许哪些特定的头部(Access-Control-Allow-Headers)和HTTP方法(Access-Control-Allow-Methods),有些指出浏览器应该缓存预检请求的最大秒数(Access-Control-Max-Age),有些表示请求源(Origin),有些头部表示是否允许浏览器在实际请求中发送Cookie(Access-Control-Allow-Credentials)。

从整体上看,Access-Control-Allow-Origin(ACAO)是与跨域授权关系最为密切的一个头部。通过这个头部,服务器能够告诉浏览器它应该信任哪些域。

不过,这种强大的能力也伴随着重大的责任。

限制太松是不行的

我们很清楚,CORS是扩展SOP策略的有用方法。 但是,我们应该考虑完全的非限制性规则所带来的安全影响。让我们看看下面的声明:

 1.png

上面的头部意味着每个源都可以访问所需的资源。这就相当于SOP出现之前,老式浏览器的早期配置。但要注意故事的另一面,正如应用安全文献所谨慎描绘的那样:

   “显然,在某些情况下,Access-Control-Allow-Origin即使取通配符值的话,也并不是不安全的。例如,如果一个允许性策略只用于提供不包含敏感信息的内容时。”

    ——《The Browser Hacker’s Handbook 》第2版,第4章 绕过同源策略

不过,你应该谨慎使用通配符。事实上,这里推荐的方法只是要对域的访问权限进行显式授权。如果服务器没有提供任何CORS头部的话,浏览器将假定同源策略(SOP)的采用上述授权。

基于Docker的情形

首先,让我们克隆“hacking-cors”[7]存储库,这样我们就可以开始进入下面的主题了:

$ git clone [email protected]:lvrosa/hacking-cors.git 

1.png

hacking-cors docker项目的目录

上面的结构展示了组成服务器镜像的docker容器和文件。

其中,“node_modules”目录(从上面“tree”命令的输出中省略掉了)也被推送到“hacking-cors”存储库。如果你遇到关于JavaScript依赖项的问题,只有在该项目的根目录下运行“npm”[8]工具即可。

$ cd hacking-cors; npm install

此外,一定要在自己的系统上安装“docker”[9] 和“docker-compose”[10],千万不要忘掉。同时,docker-compose文件使用的是版本3格式。这两个依赖项的当前版本是:

1.png

Docker和Docker Compose的版本

项目的结构

我们已经创建了两个不同的docker项目。它们可以由各自根目录下的配置Dockerfile来表示。

1.png

每个Web服务器的Docker文件

我们感兴趣的文件位于static和img目录下。它们保存着最终会被其他网页使用的各种资源。其中,JavaScript文件位于static目录下。您可以用自己喜欢的代码编辑器来打开并浏览它们。

此外,Trusted Site的img目录下存放着owasp_bug.png资源。在我们的实验中,这个图片资源将被Evil Site所请求,并尝试加载它。这同样适用于“static/hello_script.js”文件,不同之处在于,Evil Site这时会执行脚本内容,而不是加载图片。

Docker镜像与网络设置概述

1.png

docker-compose.yml内容

看看上面的docker-compose.yml文件。我们就可以确定与环境相关的重要事项,比如:

· 我们将创建两个容器(即evil_site和trusted_site);

· 容器将连接到cors_hack_net桥接网络接口;

· cors_hack_net接口将通过CIDR 10.5.0.0/16来确定子网。

作为指向容器网络地址的有用链接,建议将主机名文件(/etc/hosts)的静态查找表设置为以下内容:

1.png

/etc/hosts文件映射

Apache服务器CORS规则一览

确定受信任网站容器的名称:

 1.png

docker-compose ps命令的输出内容

登录容器:

$ docker exec -it trusted_site /bin/bash

将Apache的.htaccess配置文件转储到屏幕上:

1.png

.htaccess Apache CORS扩展规则 

如上图中强调的那样,当文件匹配规则适用时,Apache Web服务器将提供ACAO(Access-Control-Allow-Origin)头部。换句话说,如果浏览器请求一个图片(.gif、.png、.ico等),甚至是一个JavaScript.js文件的话,只有当源匹配http://trustedsite.com时,这些资源的内容才被授权由页面加载/使用。

需要注意的是,由于.htaccess文件来自htdocs目录,因此,这会影响其子结构下的所有文件。

小结

在本系列文章中,我们将为读者详细介绍HTTP CORS攻防的相关知识。首先,我们在本文中为读者介绍了同源策略及其变种,以及CORS及其常见头部等基础知识,在下一篇文章中,我们将理论联系实际,介绍具体的攻防知识。

本文翻译自:https://medium.com/bugbountywriteup/hacking-http-cors-from-inside-out-512cb125c528如若转载,请注明原文地址:


文章来源: https://www.4hou.com/posts/qDzk
如有侵权请联系:admin#unsafe.sh