在Web上使用Cross-Site Request Forgery进行劳做以后,咱们终于有了一个合适的解决方案。 没有网站全部者的技术负担,没有困难的实施,部署简单,它是Same-Site Cookies。html
跨站请求伪造,也称为CSRF或XSRF,基本上永远存在。 它源于网站必须向另外一个站点发出请求的简单功能。 假设我在此页面中嵌入了如下表单。ios
<form action="https://your-bank.com/transfer" method="POST" id="stealMoney">
<input type="hidden" name="to" value="Scott Helme">
<input type="hidden" name="account" value="14278935">
<input type="hidden" name="amount" value="£1,000">
复制代码
您的浏览器加载此页面,结果是上面的表单,而后我在页面上使用一个简单的JS提交。web
document.getElementById("stealMoney").submit();
复制代码
这就是CSRF的名称来源。 我正在伪造一个跨站点发送请求到您的银行。 这里真正的问题不是我发送了请求,而是您的浏览器会发送您的cookie。 该请求将把您当前持有的所有权限一并发送,这意味着若是您已登陆到您的银行,您就需向我捐赠1,000英镑, 谢谢! 若是您没有登陆,那么请求将是无害的,由于您没法在未登陆的状况下转帐。目前,您的银行能够经过几种方式来缓解这些CSRF攻击。跨域
我不会详细说明这些,由于网上有大量有关此主题的信息,但我想快速介绍它们以显示实施它们的技术要求。浏览器
在服务端收到请求时,会向咱们提供Origin头和Referer头来讲明请求的来源。 您能够检查其中的一个或两个值,以查看请求是否源自不一样的来源。 若是是跨域请求,则只需将其丢弃便可。 Origin和Referer头确实获得了一些防止浏览器的保护,以防止被篡改,但它们可能并不老是存在。安全
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
accept-encoding: gzip, deflate, br
cache-control: max-age=0
content-length: 166
content-type: application/x-www-form-urlencoded
dnt: 1
origin: https://report-uri.io
referer: https://report-uri.io/login
upgrade-insecure-requests: 1
user-agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36
复制代码
您可使用两种不一样的方式使用Anti-CSRF令牌,但原则保持不变。当访问者请求页面时,如上例中的转移金额页面,您将随机令牌嵌入到表单中。当真正的用户提交此表单时,将返回随机令牌,您能够检查它是否与您在表单中发出的令牌相匹配。在CSRF攻击情形中,攻击者永远没法得到此值,即便他们请求页面也没法获取此值,由于同源策略(SOP)会阻止攻击者读取包含令牌的响应。此方法运行良好,但要求站点跟踪Anti-CSRF令牌的发布和返回。相似的方法是将令牌嵌入到表单中,并向浏览器发出包含相同值的cookie。当真正的用户提交他们的表单时,cookie中的值和表单将在网站收到时匹配。当攻击者发送伪造请求时,浏览器将不会设置CSRF cookie,测试将失败。bash
<form action="https://report-uri.io/login/auth" method="POST">
<input type="hidden" name="csrf_token" value="d82c90fc4a14b01224gde6ddebc23bf0">
<input type="email" id="email" name="email">
<input type="password" id="password" name="password">
<button type="submit" class="btn btn-primary">Login</button>
</form>
复制代码
上述方法长期为咱们提供了至关强大的CSRF保护。 检查Origin和Referer头不是100%可靠,而且大多数站点采用Anti-CSRF令牌方法的一些变体。 问题是,这些都对网站提出了某种要求来实施和维护解决方案。 它们可能不是世界上技术最复杂的东西,但咱们仍然在构建一个解决方案,围绕浏览器作一些咱们不但愿它作的事情。 相反,为何咱们不告诉浏览器中止作咱们不但愿它作的事情?...如今咱们能够!cookie
您可能已经在我最近的一篇名为Tough Cookies的博客中看到过Same-Site Cookies,但我将在这里经过一些例子更深刻地介绍它。 从本质上讲,Same-Site Cookies彻底有效地抵消了CSRF攻击。Dead. Finito. Adios! 捕获咱们在网络上真正须要的本质以赢得安全战,Same-Site Cookies易于部署,很是简单。 拿你现有的cookie:网络
Set-Cookie: sess=abc123; path=/
复制代码
只需添加SameSite属性便可。并发
Set-Cookie: sess=abc123; path=/; SameSite=lax
复制代码
你完成了。 说真的,就是这样! 在cookie上启用此属性将指示浏览器为此cookie提供某些保护。 有两种模式能够在Strict或Lax中启用此保护,具体取决于您想要得到的严重程度。
SameSite=Strict
SameSite=Lax
复制代码
将SameSite保护设置为严格模式显然是首选,但咱们有两个选择的缘由是并不是全部站点都相同,也没有相同的要求。当在严格模式下操做时,浏览器根本不会在任何跨源请求上发送cookie,所以CSRF彻底死在水中。您可能遇到的惟一问题是它也不会在顶级导航上发送cookie(更改地址栏中的URL)。若是我提供了https://facebook.com的连接,而且Facebook将SameSite cookie设置为严格模式,当您单击连接到打开Facebook时,您将没法登陆。不管您是否已登陆,在新标签页中打开它,不管您作什么,从该连接访问时都不会登陆到Facebook。这对用户来讲可能有点烦人和/或意外,但确实提供了使人难以置信的强大保护。 Facebook在这里须要作的是相似于亚马逊作的,他们有2个cookie。一种是一种“基本”cookie,能够将您识别为用户,并容许您拥有登陆体验,但若是您想作一些敏感的事情,好比购买或更改账户中的内容,则须要第二个cookie, “真正的”cookie,可让你作重要的事情。在这种状况下,第一个cookie不会设置SameSite属性,由于它是一个“方便”的cookie,它实际上不容许你作任何敏感的事情,若是攻击者能够用它作出跨域请求,则没有任何反应。可是,第二个cookie(敏感cookie)将设置SameSite属性,攻击者就不能滥用权限到跨源请求中。这是用户和安全性的理想解决方案。但这并不老是可行的,由于咱们但愿SameSite cookie易于部署,这里还有第二种选择。
将SameSite保护设置为Lax模式能够修复上述用户点击连接的严格模式中提到的问题,若是他们已经登陆,则不会在目标站点上登陆。在Lax模式下,只有一个例外容许cookie附加到使用安全HTTP方法的顶级导航。 “安全”HTTP方法在RFC 7321第4.2.1节中定义为GET,HEAD,OPTIONS和TRACE,咱们对此处的GET方法感兴趣。 这意味着,当用户单击连接时,咱们对https://facebook.com的顶级导航如今在浏览器发出请求时附加了SameSite标记的cookie,从而保持了预期的用户体验。 咱们还彻底受到基于POST的CSRF攻击的保护。 回到顶部的示例,此攻击仍然没法在Lax模式下工做。
<form action="https://your-bank.com/transfer" method="POST" id="stealMoney">
<input type="hidden" name="to" value="Scott Helme">
<input type="hidden" name="account" value="14278935">
<input type="hidden" name="amount" value="£1,000">
复制代码
因为POST方法不被认为是安全的,所以浏览器不会在请求中附加cookie。 攻击者固然能够自由地将方法更改成“安全”方法并发出相同的请求。
<form action="https://your-bank.com/transfer" method="GET" id="stealMoney">
<input type="hidden" name="to" value="Scott Helme">
<input type="hidden" name="account" value="14278935">
<input type="hidden" name="amount" value="£1,000">
复制代码
只要咱们不接受GET请求代替POST请求,那么这种攻击是不可能的,可是在Lax模式下操做时须要注意。 此外,若是攻击者能够触发顶级导航或弹出新窗口,他们还可使浏览器发出附加了cookie的GET请求。 这是在Lax模式下运营的权衡,咱们保持用户体验不变,但也有较小的风险接受付款。
此博客旨在使用SameSite Cookie缓解CSRF,但正如您可能已经猜到的那样,此机制也有其余用途。 规范中列出的第一个是跨站点脚本包含(XSSI),浏览器在此处请求资源,例如脚本,该脚本将根据用户是否通过身份验证而更改。 在跨站点请求方案中,攻击者不能滥用SameSite Cookie的环境权限来产生不一样的响应。 此处详细介绍了一些有趣的计时攻击,那能够有效缓解滥用状况。
另外一个不详细的有趣用途是防止在BEAST式压缩攻击(CRIME,BREACH,HEIST,TIME)中泄露会话cookie的价值。 这是很是高级别的,但基本状况是MiTM能够强制浏览器经过他们喜欢的任何机制发出跨源请求并监视它们。 经过滥用请求有效负载大小的变化,攻击者能够经过改变浏览器发出的请求并在线路上观察它们的大小,一次一个字节地猜想会话ID值。 使用SameSite Cookies,浏览器不会在此类请求中包含cookie,所以攻击者没法猜想其值。
随着浏览器中大多数新的安全功能,您能够指望Firefox或Chrome的领导这项功能,这里的状况也不例外。 自v51以来,Chrome已经支持Same-Site Cookies,这意味着Android上的Opera,Android浏览器和Chrome也有支持。 您能够在caniuse.com上查看列出当前支持的详细信息,Firefox也有一个bug,能够添加支持。 尽管支持还没有普及,但咱们仍应将SameSite属性添加到cookie中。 理解它的浏览器将尊重设置并提供cookie额外的保护,而那些不理解它的人将彻底忽略它并继续前行。 这里没有什么可失去的,它造成了一个很是好的防护深度方法。 咱们能够考虑删除传统的反CSRF机制,可是在这些机制之上添加SameSite会给咱们带来难以置信的强大防护。
原文:scotthelme.co.uk/csrf-is-dea… 原文发布日期:2017年2月20日 做者:Scott Helme 译者:帕奇式
翻译及转载得到做者许可:
![]()