Ajax保护ASP.NET 应用免受 CSRF 攻击

CSRF是什么?

  CSRF(Cross-site request
forgery),中文名称:跨站请求伪造,也为名:one click attack/session
riding,缩写为:CSRF/XSRF。CSRF(Cross Site Request Forgery,
跨站域请求伪造)是一致种植网络的攻击方式,它以 2007 年曾经深受列为互联网 20
大安全隐患之一。其他安全隐患,比如 SQL
脚论注入,跨站域脚论攻击等在前不久已经逐步为人们熟知,很多网站也还指向他们开展了防守。然而,对于多数丁来说,CSRF
却依然是一个生的概念。即便是闻名遐迩的 Gmail, 在 2007 年的也是正在
CSRF 漏洞,从而为黑客攻击而而 Gmail 的用户造成巨大的损失。

CSRF可以开啊?

  你立即好如此理解CSRF攻击:攻击者盗用了您的身份,以你的名义发送恶意请求。CSRF能够开的政工包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账……造成的题目包括:个人隐私泄露和资产安全。

CSRF攻击原理

自打上图可以看来,要就同样蹩脚CSRF攻击,受害者必须逐项完成两独步骤:

  1.登录受信任网站A,并在地头生成Cookie。

  2.每当未登出A的状态下,访问危险网站B。

  看这里,你恐怕会说:“如果自己无满足上述两只尺码中的一个,我哪怕未会见遭到CSRF的攻击”。是的,确实如此,但您不可知担保以下状况不会见来:

  1.公切莫可知确保你登录了一个网站后,不再打开一个tab页面并访问另外的网站。

  2.你无能够确保你关闭浏览器了晚,你本地的Cookie立刻过期,你上次之对话已经收尾。(事实上,关闭浏览器不能够了事一个会话,但大部分人口且见面错的觉得关闭浏览器就当退出登录/结束会见说话了……)

  3.直达图中所谓的口诛笔伐网站,可能是一个是其他漏洞的可信任的常常给人走访的网站。

方盖地提了瞬间CSRF攻击的思辨,下面我以因此个例详细说说具体的CSRF攻击,这里自己为一个银行转账的操作作为例子(仅仅是例证,真实的银行网站没有这样傻:>)

  银行网站A,它为GET请求来形成银行转化的操作,如:http://www.mybank.com/Transfer.php?toBankId=11&money=1000

  危险网站B,它里面来同段HTML的代码如下:

  <img
src=http://www.mybank.com/Transfer.php?toBankId=11&money=1000&gt;

  首先,你登录了银行网站A,然后访问危险网站B,噢,这时你晤面意识你的银行账户少了1000块……

  为什么会这样啊?原因是银行网站A违反了HTTP规范,使用GET请求更新资源。在走访危险网站B的前,你早已报到了银行网站A,而B中的<img>以GET的章程呼吁第三正在资源(这里的老三正虽是据银行网站了,原本这是一个合法的求,但这边给不法分子用了),所以您的浏览器会带来达而的银行网站A的Cookie发出Get请求,去赢得资源“http://www.mybank.com/Transfer.php?toBankId=11&money=1000”,结果银行网站服务器收到请求后,认为这是一个更新资源操作(转账操作),所以就立刻进行转账操作……

现阶段守 CSRF 的几乎种植政策

于业界目前守 CSRF 攻击主要有三栽政策:验证 HTTP Referer
字段;在请地址被补充加 token 并说明;在 HTTP
头中由定义属性并说明。下面就分别对就三栽政策进行详尽介绍。

验证 HTTP Referer 字段

基于 HTTP 协议,在 HTTP 头中有一个字段叫 Referer,它记录了该 HTTP
请求的源地址。在普通状态下,访问一个安康受限页面的请求来自于同一个网站,比如要拜访
http://bank.example/withdraw?account=bob&amount=1000000&for=Mallory,用户必须先登陆
bank.example,然后经点击页面上的按钮来点转账事件。这时,该转帐请求的
Referer 值就见面是转发按钮所于的页面的 URL,通常是盖 bank.example
域名开始的地址。而若黑客要对银行网站实施 CSRF
攻击,他只得在他好之网站组织请求,当用户通过黑客的网站发送请求到银行经常,该要的
Referer 是负为黑客自己的网站。因此,要守护 CSRF
攻击,银行网站仅待对此每一个转速要验证其 Referer 值,如果是盖
bank.example
开头的域名,则证明该要是出自银行网站自己的恳求,是官方的。如果 Referer
是另外网站的话语,则发出或是黑客的 CSRF 攻击,拒绝该要。

这种办法的明朗的好处就简单易行,网站的便开发人员不欲担心 CSRF
的狐狸尾巴,只待以末让有安全敏感的乞求统一多一个拦截器来检查 Referer
的值就可。特别是对于目前现有的系,不需转移目前网的别已发代码和逻辑,没有风险,非常便捷。

然,这种措施毫无万无一失。Referer 的价是由浏览器提供的,虽然 HTTP
协议达成有鲜明的渴求,但是每个浏览器对于 Referer
的切实可行落实可能发生异样,并无克管浏览器自身没有安全漏洞。使用验证 Referer
值的章程,就是管安全性都依靠让第三正值(即浏览器)来保持,从理论及来讲,这样并无安全。事实上,对于某些浏览器,比如
IE6 或 FF2,目前都出一些术可篡改 Referer 值。如果 bank.example
网站支持 IE6 浏览器,黑客完全好拿用户浏览器的 Referer 值设为以
bank.example 域名开始的地址,这样便可以通过认证,从而进行 CSRF 攻击。

哪怕是利用新型的浏览器,黑客无法篡改 Referer
值,这种方式还是发生题目。因为 Referer
值会记录下用户的拜会来源,有些用户觉得这么见面犯到他们协调之隐私权,特别是有几组织担心
Referer
值会拿组织内网中的少数信息泄露及外网中。因此,用户自己好安装浏览器使该以发送请求时不再提供
Referer。当他们正常访问银行网站经常,网站会盖请没有 Referer 值而以为是
CSRF 攻击,拒绝法定用户之拜会。

当求地址被上加 token 并证实

CSRF
攻击之所以能成,是为黑客可以完全伪造用户的求,该要中兼有的用户征信息都是存在于
cookie 中,因此黑客可以于匪懂得这些证明信息的气象下直以用户自己的
cookie 来通过平安认证。要抵挡
CSRF,关键在于在伸手被放入黑客所未可知伪造的音信,并且该信息不存在于
cookie 之中。可以当 HTTP 请求中以参数的款式进入一个即兴产生的
token,并于劳动器端建立一个拦截器来说明这个 token,如果请被无 token
或者 token 内容不正确,则以为可能是 CSRF 攻击而不肯该要。

这种办法要较检查 Referer 要安全有,token 可以在用户登陆后有并放于
session 之中,然后于每次要时拿 token 从 session 中以出,与请求被之
token 进行比对,但这种方法的难处在于怎样拿 token
以参数的花样进入请求。对于 GET 请求,token 将附在请求地址后,这样 URL
就成为 http://url?csrftoken=tokenvalue。 而于 POST 请求来说,要以 form
的末段加上 <input type=”hidden” name=”csrftoken”
value=”tokenvalue”/>,这样就算管 token
以参数的花样进入请求了。但是,在一个网站被,可以承受请求的地方特别多,要对此各一个请求都添加
token
是老烦的,并且非常爱漏掉,通常使用的法子就是是在历次页面加载时,使用
javascript 遍历整个 dom 树,对于 dom 中所有的 a 和 form 标签后加盟
token。这样可以解决大部分之恳求,但是对当页面加载后动态变化的 html
代码,这种方式就从未打算,还索要程序员在编码时手动添加 token。

该方式还有一个缺陷是难管教 token
本身的安全。特别是在一些论坛之类支持用户自己上内容之网站,黑客可以在面公布自己个人网站的地方。由于系统为会见以斯地址后长
token,黑客可以在团结之网站及获这 token,并马上便得动员 CSRF
攻击。为了避免这一点,系统可于增长 token
的时候长一个论断,如果是链接是链到自己本站的,就于末端加加
token,如果是奔外网则免加。不过,即使这 csrftoken
不为参数的花样附加以伸手中,黑客的网站也如出一辙可由此 Referer
来取得这个 token 值以动员 CSRF 攻击。这为是有的用户喜爱手动关闭浏览器
Referer 功能的因由。

每当 HTTP 头中于定义属性并证实

这种办法呢是使 token 并进行说明,和及等同栽艺术不同的是,这里并无是把
token 以参数的花样置于 HTTP 请求中,而是把其内置 HTTP
头中自定义的特性里。通过 XMLHttpRequest
这个仿佛,可以一次性吃所有此类请求加上 csrftoken 这个 HTTP 头属性,并把
token 值放入其中。这样化解了上种方法以呼吁被进入 token
的困苦,同时,通过 XMLHttpRequest
请求的地址不会见于记录及浏览器的地址栏,也无用担心 token 会透过 Referer
泄露及另外网站受失去。

然而这种艺术的局限性非常坏。XMLHttpRequest 请求通常用于 Ajax
方法中对页面局部的异步刷新,并非有的呼吁都合乎用此近乎来倡导,而且经过此类请求得到的页面不克叫浏览器所记录下,从而进行发展,后退,刷新,收藏等操作,给用户带来不方便。另外,对于没有展开
CSRF 防护的遗留系统来说,要运这种方式来拓展防范,要拿装有请求都改吗
XMLHttpRequest 请求,这样几是如更写尽网站,这代价的是不能够接受的。

 

CSRF的防御

  我总了一下收看底素材,CSRF的守护可以从服务端和客户端两方着手,防御机能是由服务端着手效果比好,现在相似的CSRF防御也还以劳务端进行。这里被大家介绍一个开源项目,具体的情可参考作者的博客《Protecting
ASP.NET Applications Against CSRF
Attacks》。

1、通过Nuget 安装ARMOR Web Framework

PM> Install-Package Daishi.Armor.WebFramework

2、添加几单布局起

<add key=“IsArmed” value=“``true``” />

<add key=“ArmorEncryptionKey” value=“{Encryption Key}” />

<add key=“ArmorHashKey” value=“{Hashing Key}” />

<add key=“ArmorTimeout” value=“1200000” />

IsArmed: 打开或者关闭ARMOR 功能开关

ArmorEncryptionKey:ARMOR 的加密密钥,用于加密和解密Token

ArmorHashKey:用于转移与验证ARMOR 哈希值,包含在让牌内。ARMOR
用这个实现是否token被篡改了。

ArmorTimeout:以毫秒为单位之ARMOR 的token有效期

好就此脚的立即段代码去变通

byte``[] encryptionKey = ``new byte``[32];

byte``[] hashingKey = ``new byte``[32];

using (``var provider = ``new RNGCryptoServiceProvider()) {

``provider.GetBytes(encryptionKey);

``provider.GetBytes(hashingKey);

3、应用程序中加入 一个ARMOR 钩子

ARMOR主要有Authorization Filter、 Fortification Filter 和 ARMOR UI
Components,支持ASP.NET MVC和ASP.NET Web
API具体的下方式可参考Protecting ASP.NET Applications Against CSRF
Attacks。

 

参考文章:

[1].Preventing CSRF

[2].Security Corner: Cross-Site Request
Forgeries

[3].《深入剖析跨站请求伪造漏洞:原理分析》

[4].《Web安全测试的过站要伪造(CSRF)》

[5].《深入解析跨站请求伪造漏洞:实例讲解》

相关文章