CSRF漏洞前世今生

大家有没有发现随着时间的推移,提及CSRF漏洞的次数越来越少,而且OWASP十大网站安全风险排名也早已经没有CSRF的踪影了,是开发人员的风险意识越来越高了吗?还是该漏洞已经被历史淘汰了?下面开始随着我来具体探寻一下CSRF漏洞的前世今生吧

一、CSRF介绍

跨站请求伪造 (CSRF),也称为 XSRF, 是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法。跟跨网站脚本(XSS)相比,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任

1、攻击细节

跨站请求攻击,简单地说,是攻击者通过一些技术手段欺骗用户的浏览器去访问一个自己曾经认证过的网站并运行一些操作(如发邮件,发消息,甚至财产操作如转账和购买商品)。由于浏览器曾经认证过,所以被访问的网站会认为是真正的用户操作而去运行。这利用了web中用户身份验证的一个漏洞:简单的身份验证只能保证请求发自某个用户的浏览器,却不能保证请求本身是用户自愿发出的。

2、具体示例

假如一家银行用以运行转账操作的URL地址如下:https://bank.example.com/withdraw?account=AccoutName&amount=1000&for=PayeeName 那么,一个恶意攻击者可以在另一个网站上放置如下代码:

 <img src="https://bank.example.com/withdraw?account=Alice&amount=1000&for=Badman" />

如果有账户名为张三的用户访问了恶意站点,而他之前刚访问过银行不久,登录信息尚未过期,那么他就会损失1000资金。

这种恶意的网址可以有很多种形式,藏身于网页中的许多地方。此外,攻击者也不需要控制放置恶意网址的网站。例如他可以将这种地址藏在论坛,博客等任何用户生成内容的网站中。这意味着如果服务端没有合适的防御措施的话,用户即使访问熟悉的可信网站也有受攻击的危险。

透过例子能够看出,攻击者并不能通过CSRF攻击来直接获取用户的账户控制权,也不能直接窃取用户的任何信息。他们能做到的,是欺骗用户的浏览器,让其以用户的名义运行操作。

二、常见防御手段

1、令牌同步模式

令牌同步模式(英语:Synchronizer token pattern,简称STP)。原理是:当用户发送请求时,服务器端应用将令牌(英语:token,一个保密且唯一的值)嵌入HTML表格,并发送给客户端。客户端提交HTML表格时候,会将令牌发送到服务端,令牌的验证是由服务端实行的。令牌可以通过任何方式生成,只要确保随机性和唯一性(如:使用随机种子【英语:random seed】的哈希链 )。这样确保攻击者发送请求时候,由于没有该令牌而无法通过验证。Django框架默认带有STP功能:

<form method="post">
    {% csrf_token %}
</form>

渲染后的效果如下:

<form method="post">
    <input type="hidden" name="csrfmiddlewaretoken" value="KbyUmhTLMpYj7CD2di7JKP1P3qmLlkPt" />
</form>

STP能在HTML下运作顺利,但会导致服务端的复杂度升高,复杂度源于令牌的生成和验证。因为令牌是唯一且随机,如果每个表格都使用一个唯一的令牌,那么当页面过多时,服务器由于生产令牌而导致的负担也会增加。而使用会话(英语:session)等级的令牌代替的话,服务器的负担将没有那么重。

2、检查Referer字段

HTTP头中有一个Referer字段,这个字段用以标明请求来源于哪个地址。在处理敏感数据请求时,通常来说,Referer字段应和请求的地址位于同一域名下。以上文银行操作为例,Referer字段地址通常应该是转账按钮所在的网页地址,应该也位于bank.example.com之下。而如果是CSRF攻击传来的请求,Referer字段会是包含恶意网址的地址,不会位于bank.example.com之下,这时候服务器就能识别出恶意的访问。这种办法简单易行,工作量低,仅需要在关键访问处增加一步校验。但这种办法也有其局限性,因其完全依赖浏览器发送正确的Referer字段。虽然http协议对此字段的内容有明确的规定,但并无法保证来访的浏览器的具体实现,亦无法保证浏览器没有安全漏洞影响到此字段。并且也存在攻击者攻击某些浏览器,篡改其Referer字段的可能。

3、添加校验token

由于CSRF的本质在于攻击者欺骗用户去访问自己设置的地址,所以如果要求在访问敏感数据请求时,要求用户浏览器提供不保存在cookie中,并且攻击者无法伪造的数据作为校验,那么攻击者就无法再运行CSRF攻击。这种数据通常是窗体中的一个数据项。服务器将其生成并附加在窗体中,其内容是一个伪随机数。当客户端通过窗体提交请求时,这个伪随机数也一并提交上去以供校验。正常的访问时,客户端浏览器能够正确得到并传回这个伪随机数,而通过CSRF传来的欺骗性攻击中,攻击者无从事先得知这个伪随机数的值,服务端就会因为校验token的值为空或者错误,拒绝这个可疑请求。

4、引入Same-Site Cookie 属性

谷歌浏览器于 3 月 29 日开始支持开始支持新的 cookie 属性,其他流行的浏览器也紧随其后,现在有一个解决方案。它称为Same-Site cookie 属性。开发人员现在可以指示浏览器控制 cookie 是否与第三方网站发起的请求一起发送 – 通过使用 SameSite cookie 属性,这是比拒绝发送 cookie 更实用的解决方案。

为 cookie 设置 Same-Site 属性非常简单。它只包括向 cookie 添加一条指令。只需添加 ‘SameSite=Lax’ 或 ‘SameSite=Strict’ 就足够了!

Set-Cookie: CookieName=CookieValue; SameSite=Lax;
Set-Cookie: CookieName=CookieValue; SameSite=Strict;

三、为什么CSRF变少了?

Chrome 80 默认将没有设置SameSite设置为SameSite=Lax,默认Post方式将不发送Cookie,仅Get请求会携带Cookie,这导致CSRF可利用的场景越来越少,所以CSRF漏洞也越来越少的人去提及了。

SameSite一共有三种值:

①、Strict Scrict最为严格,完全禁止第三方Cookie,跨站点时,任何情况下都不会发送Cookie

②、Lax Lax规则稍稍放宽,大多数情况也是不发送第三方 Cookie,但是导航到目标网址的 Get 请求除外。

③、None 网站可以选择显式关闭SameSite属性,将其设为None。不过,前提是必须同时设置Secure属性(Cookie 只能通过 HTTPS 协议发送),否则无效

CSRF漏洞前世今生

关闭SameSite属性操作方法

  • 谷歌浏览器地址栏输入:chrome://flags/
  • 找到:SameSite by default cookies、Cookies without SameSite must be secure
  • 设置上面这两项设置成 Disable
CSRF漏洞前世今生


原文始发于微信公众号(洋洋自语):CSRF漏洞前世今生

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/273003.html

(0)
明月予我的头像明月予我bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!