Quantcast
Channel: CodeSection,代码区,网络安全 - CodeSec
Viewing all articles
Browse latest Browse all 12749

【技术分享】让我们一起来消灭CSRF跨站请求伪造(下)

$
0
0
【技术分享】让我们一起来消灭CSRF跨站请求伪造(下)

2017-11-02 10:57:20

阅读:1285次
点赞(0)
收藏
来源: medium.com





【技术分享】让我们一起来消灭CSRF跨站请求伪造(下)

作者:WisFree





【技术分享】让我们一起来消灭CSRF跨站请求伪造(下)

译者:WisFree

预估稿费:200RMB

投稿方式:发送邮件至linwei#360.cn,或登陆网页版在线投稿


传送门

【技术分享】让我们一起来消灭CSRF跨站请求伪造(上)


写在前面的话

在本系列文章的上集中,我们跟大家介绍了关于CSRF的一些基本概念,并对常见的几种CSRF漏洞类型进行了讲解。那么接下来,我们就要跟大家讨论一下如何才能消灭CSRF。


现代保护机制

实际上,通过修改应用程序源代码来实现CSRF保护在很多情况下是不现实的,要么就是源代码无法获取,要么就是修改应用程序的风险太高了。但我们所设计的解决方案可以轻松地部署到RASP、WAF、反向代理或均衡负载器中,并且可以同时保护一个或多个配置相同的应用程序。

首先我们要知道,正确地使用安全或不安全的HTTP verb是非常重要的。虽然这一点并不能构成一个有效的解决方案,但它是另外两种方法实现的基础。在构建应用程序之前,我们需要对其进行架构设计。幸运的是,大多数现代Web框架都有路由的概念,并且可以强制让节点与HTTP verb配对。在现代框架中,带有错误verb的请求将会导致错误的产生。如果你的应用程序中不能实现这种机制的话,请继续往下看。

另一种方法是验证请求的发送源,这种方法可以确保发送给应用程序的请求来自于一个受信任的源。在这里,正确使用HTTP verb同样是非常重要的,如果我们假设只有改变状态的请求会来自于不安全的请求,那我们就只需要对不安全的请求源进行验证就可以了。但正如我们之前所讨论的,在验证源的可靠性时我们还会遇到很多的问题。其中的一种解决方案是创建一个安全URL白名单,这样就可以防止来自外部源的CSRF。

第三种方法,也是最常见的方法,即使用令牌Token。令牌本身有多种形式,但大多数使用的都是同步器令牌(synchronizer token)。说得更加详细一点,这种令牌主要分为“双提交令牌”以及“加密令牌”。事实证明,结合使用双提交令牌以及加密令牌可以提供最好的安全性。

简单说来,所谓的同步器令牌,就是服务器和浏览器之间需要同步一个令牌(唯一的)。安全的请求方法会返回一个令牌,当浏览器在发送请求时会携带这个令牌,而服务器在处理请求之前,会验证令牌的有效性。处理完请求之后,服务器还会提供一个新的令牌以保证之前的令牌无法继续使用(防止重放攻击)。此时,攻击者将无法访问到令牌或者将其插入到恶意请求之中,因为如果攻击者想这样做的话,他必须要强迫目标用户向远程网站发送请求并访问请求内容,但SOP可以防止这种情况的发生。这样一来,攻击者所能使用的最后一种方法就是利用目标程序可能存在的XSS漏洞了。

需要注意的是,令牌主要有四个部分(一个随机数,用户识别符,过期时间以及真实性验证信息)组成,因此保持其“整体完整性”就非常重要了,其中缺少任何一项都将导致令牌的安全性大打折扣。

在令牌机制的实现过程中,有两个方面我们需要仔细斟酌,即服务器端和客户端。其中,服务器端负责生成和验证令牌,而客户端负责向需要请求资源的服务器发送令牌。需要注意的是,大家绝对有必要为每一个请求生成一个新的令牌,即使这样会牺牲一定的性能。除此之外,你也可以在cookie中添加令牌,但你需要确保cookie没有使用HttpOnly标记。下面这段简单的示例代码是生成令牌的常用方法:

StringgenerateToken(intuserId,intkey){ byte[16]data=random() expires=time()+3600 raw=hex(data)+"-"+userId+"-"+expires signature=hmac(sha256,raw,key) returnraw+"-"+signature }

大家可以从上面这段代码中看到组成令牌的那四个部分。其中,HMAC是用于验证前三个元素有效性的令牌,并最终会添加到raw的结尾。

boolvalidateToken(token,user){ parts=token.split("-") str=parts[0]+"-"+parts[1]+"-"+parts[2] generated=hmac(sha256,str,key) if!constantCompare(generated,parts[3]){ returnfalse } ifparts[2]<time(){ returnfalse } ifparts[1]!=user{ returnfalse } returntrue }

上面这段示例代码演示的是验证和计算令牌有效性的常用方法。首先我们需要将令牌拆分成它的四个组成部分,然后第一步就是利用前三个部分生成并验证HMAC的有效性(与之前的HMAC进行对比)。对比时间一定要确保使用的是固定时间,这样可以避免基于时间的攻击。如果验证成功,我们接下来就要确保令牌没有过期,最后进行用户匹配。但在真实场景中,最麻烦的事情就是让用户的浏览器在发送所有请求时自动提交令牌。

实际上在开发应用的过程中,绝大多数的现代框架都已经帮我们搞定这一切了。框架库可以处理XHR,并将令牌自动插入到请求信息(包括表单)中。但是如果框架没有帮我们实现的话,我们也可以自己实现这种功能。这一步主要可以分为两个部分,一个是处理表单提交,另一个是处理XHR。下面这段示例代码可以处理onclick事件回调:

vartarget=evt.target; while(target!==null){ if(target.nodeName==='A'||target.nodeName=== 'INPUT'||target.nodeName==='BUTTON'){ break; } target=target.parentNode; } //Wedidn'tfindanyofthedelegates,bailout if(target===null){ return; }

我们可以将这段代码添加到文档中,而不是添加到单独的表单或可点击的元素之中,因为很有可能表单或元素根本就不存在与页面DOM之中。我们所指的元素是用户可以点击的东西,由于DOM树的结构以及事件处理系统的不同,所以我们要寻找的是那种可以提交表单的元素,例如input或button标签。

接下来,我们可以检测一个标签是否为input标签。如果它是,那么我们就可以确保这里有一个提交按钮了。当我们验证提交事件已经被触发之后,我们就可以继续搜索DOM树并寻找form标签了。如果找遍了DOM树却没有找到form标签,那么就说明元素没有被提交,除非它使用了XHR。找到form标签之后,最后一步就是将令牌以一个隐藏input元素添加到表单之中,即创建一个新的元素并将其添加到表单。

vartoken= form.querySelector('input[name="csrf_token"]'); vartokenValue=getCookieValue('CSRF-TOKEN'); if(token!==undefined&&token!==null){ if(token.value!==tokenValue){ token.value=tokenValue; } return; } varnewToken=document.createElement('input'); newToken.setAttribute('type','hidden'); newToken.setAttribute('name','csrf_token'); newToken.setAttribute('value',tokenValue); form.appendChild(newToken);

对于那些并非基于表单的请求,我们就需要想办法将令牌插入到XHR请求之中了。大多数代码库都提供了相关的抽象方法,包括jQuery,但我们需要针对标准XHR API创建我们自己的函数钩子。通过利用javascript的原型继承机制以及动态特性,我们可以直接将原始的发送方法添加到对象之中,这样我们就可以随时调用这些方法了。接下来,我们需要创建一个新的函数并将令牌插入到cookie中,然后再在请求信息中添加一个带值的header。

不过需要注意的是,对于IE浏览器,我们所设计的这种方法只适用于IE 8及其以上版本的IE浏览器,因为这些版本才支持方法原型和XHR,虽然IE支持XHR但并不支持方法原型。具体的浏览器支持情况如下图所示:


【技术分享】让我们一起来消灭CSRF跨站请求伪造(下)

总结

在本系列文章中,我们跟大家介绍了关于CSRF的一些基本概念,并对常见的几种CSRF漏洞类型进行了讲解。除此之外,我们还给大家提供了一些用于对付CSRF漏洞的最佳实践方法。这里我给大家推荐一款名叫Same-Site的扩展插件,它可以帮助我们对cookie进行检测,并对浏览器所发送的cookie进行严格的安全限制。这款插件的浏览器支持情况如下图所示:


【技术分享】让我们一起来消灭CSRF跨站请求伪造(下)


【技术分享】让我们一起来消灭CSRF跨站请求伪造(下)
【技术分享】让我们一起来消灭CSRF跨站请求伪造(下)
本文由 安全客 翻译,转载请注明“转自安全客”,并附上链接。
原文链接:https://medium.com/@jrozner/wiping-out-csrf-ded97ae7e83f

Viewing all articles
Browse latest Browse all 12749

Latest Images

Trending Articles





Latest Images