使用相同站点Cookie属性防止CSRF攻击


网络曲奇简介

因为超文本传输协议是一种无状态协议,所以它不能在内部区分不同的用户。为了解决这个问题,1994年发明了cookie技术。通过使用cookies,服务器指示浏览器保存一个唯一的密钥,然后将它与向服务器发出的每个请求一起发回。

当请求从浏览器发送到网站时,浏览器会检查是否有属于该网站的存储的cookie。在执行此过程时,它会检查cookies的属性和标志(域、路径、安全)是否与所请求的网站数据相匹配。如果它们匹配,浏览器会随请求一起发送相关的cookies。

Cookies误用会导致跨站点请求伪造

对于第三方通过浏览器发出的请求,也以同样的方式重复这种行为。“第三方”是指我们不直接访问的其他网站。临界点来自web application security观点是,当你访问网站A时,保存在浏览器中的网站B的所有cookies都将被添加到网站A向网站B发起的请求中。因此,浏览器上属于网站B的会话可能会被使用,甚至被滥用。

在安全术语中,滥用这种浏览器行为被称为跨站点请求伪造(CSRF)。这是通过使用这种浏览器行为误用属于授权用户的会话来实现的。

这种浏览器行为也可能被滥用于其他目的,如跟踪用户或广告。当你进入一个网站,例如example.com,你的浏览器可能会因为网页上的超文本标记语言元素而向不同的网站发出一些请求example.com例如,脸书类按钮、谷歌分析代码等。随着这些请求,浏览器中属于这些其他站点的cookies也将被发送。因此,这些第三方可以通过使用Cookie和推荐人信息来跟踪和记录您的活动。

您应该阻止跨站点请求以阻止CSRF吗?

通常,在火狐和铬浏览器中避免这样的跟踪是可能的。但是,当这些浏览器阻止跟踪时,它们会阻止任何第三方网站发送cookies和请求。但是,这样做,你的浏览体验会非常差。所以,通过封锁饼干,你可以完全阻止CSRF,但这值得后果吗?

引入同站点Cookie属性防止CSRF攻击

多亏了谷歌浏览器的一个新的cookie属性started supporting on the 29th of March,以及其他流行的浏览器,现在有了一个解决方案。它被称为相同站点Cookie属性。开发人员现在可以通过使用SameSite Cookie属性来指示浏览器控制Cookie是否与第三方网站发起的请求一起发送,这是比拒绝发送Cookie更实用的解决方案。

为cookie设置同站点属性非常简单。它只包括向cookie中添加一条指令。简单地添加“相同站点=宽松”或“相同站点=严格”就足够了!

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


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

严格和宽松的相同站点Cookie属性之间的差异

严格:顾名思义,这是严格应用相同站点规则的选项。当“相同站点”属性设置为“严格”时,cookie不会随第三方网站发起的请求一起发送。

将cookie设置为“严格”会对浏览体验产生负面影响。例如,如果你点击一个指向Facebook个人资料页面的链接,如果Facebook.com将其cookie设置为SameSite=Strict,除非您再次登录Facebook,否则您无法继续在Facebook上导航(查看Facebook页面)。原因是脸书的cookie不是通过这个请求发送的。

Lax:当您将cookie的SameSite属性设置为Lax时,该cookie将与第三方网站发起的GET请求一起发送。

这里重要的一点是,要发送带有获取请求的cookie,所做的获取请求必须导致顶级导航。只有这样才能发送设置为LAX的cookie。让我多解释一下。

资源可以通过以下方式加载iframe,img,和script 标签。这些请求也可以作为GET请求来操作,但是它们都不会导致顶层导航。基本上,他们不会改变你地址栏中的网址。因为这些获取请求不会导致顶级导航,所以设置为Lax的cookies不会随它们一起发送。

有关更多说明,请参见下表:

请求类型 示例代码 发送的Cookies
< a href= " ... "> </a > 正常,Lax
Perender < link rel="prerender" href= " .. "/> 正常,Lax
表格GET < form method="GET" action= " ... "> 正常,Lax
表单POST < form method="POST" action= " ... "> 标准
iframe < iframe src= " ... "> </iframe > 标准
AJAX 美元。获取(" ... ")( 标准
图像 < img src= " ... ">

标准

这真的意味着对CSRF的“再见”吗?

是的,看起来SameSite cookie属性是抵御CSRF攻击的有效安全措施。通过使用此功能,您可以避免在第三方发起请求时发送cookies。让我用一个例子来说明。

假设您已经登录到该网站www.badbank.com。利用网络钓鱼攻击,攻击者可以诱骗您进入www.attacker.com在另一个浏览器选项卡中。在上使用代码www.attacker.com,攻击者试图通过向您的帐户发送表单来转移资金www.badbank.com。您的浏览器发送属于的cookiewww.badbank.com有了这个请求。如果表单打开www.badbank.com缺少防止CSRF攻击的CSRF令牌,攻击者可以利用您的会话。

如果饼干www.badbank.com被设定为SameSite=Lax浏览器中的cookie不会随开机自检请求一起发送,攻击也不会成功。

CSRF的受欢迎程度正在下降

在2010年发布的OWASP十大攻击名单中,CSRF攻击排在第5位,但在2011年下降到第8位OWASP Top Ten in 2013。人们认为,这是因为人们对CSRF的认识有所提高,以及框架普遍使用反CSRF标志。

2017年,CSFR排名第八OWASP Top 10

防止CSRF漏洞

虽然我们现在使用了相同的站点Cookie属性,但是我们仍然应该小心!我们应该用POST请求而不是GET来进行更改。

GET是为导航目的而设计的,而不是为状态改变而设计的,所以使用GET请求通常被认为是一种安全的方法。但是,当我们执行操作(如订购产品、更改密码或编辑配置文件信息)时,使用开机自检请求要安全得多。

这有3个重要原因:

  • 当参数由GET携带时,它们会保留在浏览器历史中。它们也将被放在服务器日志和向第三方发出的请求中的引用头中。
  • 不使用获取请求的另一个原因是,设置为Lax的cookies仍然与获取请求一起发送,这给了攻击者另一个利用用户的机会。
  • 最后,通过使用GET利用CSRF漏洞要容易得多。要利用GET形式的CSRF漏洞,攻击者不必拥有一个站点。他可以将这个有效负载注入论坛消息、帖子评论或图像标签中。