C# AntiForgeryToken防XSRF漏洞攻击

本文详细介绍了XSRF攻击的概念及其危害,重点阐述了ASP.NET的AntiForgeryToken机制如何防止此类攻击。通过生成和比较加密的Token,确保了请求的合法性。同时,分析了AntiForgeryToken的实现细节,包括Token的生成、存储、验证过程,以及在负载均衡环境下的注意事项。
摘要由CSDN通过智能技术生成

1.XSRF:跨站请求伪造

XSRF即在访问B站点的时候,执行了A站点的功能。
比如:
A站点登录后,可以修改用户的邮箱(接口:/Email/Modify?email=123),修改邮箱时只验证用户有没有登录,而且登录信息是保存在cookie中。
用户登录A站点后,又打开一个窗口访问B站点,如果这时B站点内嵌入了一条链接http://www.A.com/Email/Modify?email=123,当用户点击这条链接时会直接修改A站点的用户邮箱。

2.ASP.NET 防XSRF攻击

ASP.NET提供了AntiForgery类防止XSRF攻击。 AntiForgery的使用如下:
在ASP.NET页面中添加如下代码

@Html.AntiForgeryToken()

在Controller的Action上添加属性ValidateAntiForgeryToken

[ValidateAntiForgeryToken]
public ActionResult IndexPost()
{
      return View("~/Views/Home/Index.cshtml");
 }

这样IndexPost就能防止XSRF攻击。

3.AntiForgery防XSRF攻击原理

在执行@Html.AntiForgeryToken()语句时,会在cookie中写入一个经过加密后的数据,并在页面中添加一个隐藏域一并写入加密后的数据(默认名称为__RequestVerificationToken)。当执行IndexPost(前面示例)方法前,会判断cookie中的数据与隐藏域的数据是否相等。相等则验证通过。否则会抛出异常。(Post请求会自动把隐藏域传递到后台,如果是Get请求,就需要手动把隐藏域的值传递到后台)。
待加密的数据是一个AntiForgeryToken对象。系统进行验证时,会先把加密的数据还原成AntiForgeryToken对象,对象有一个SecurityToken属性(用于填充随机序列),系统主要判断该字段的值是否相等。
同一个会话期间,SecurityToken数据相同,所以即使开多个tab访问相同页面,数据验证也会通过。
同一个会话期间cookie中的加密数据不会改变,因为访问页面时,cookie会传到后台,后台判断cookie中有加密数据,就不会重新生成cookie数据。但隐藏域的值每次都不同,因为每访问一次页面,都会重新加密一次,虽然AntiForgeryToken对象的值相同,但通过MachineKey的Protect加密后,每次加密的值都会不同。
AntiForgery使用MachineKey进行加密,所以如果系统使用负载均衡,就需要配置MachineKey,否则不同服务器的MachineKey不同,导致无法解密。

4.源码解析

1)在执行@Html.AntiForgeryToken()语句时,会调用GetHtml方法。GetHtml方法中会调用GetFormInputElement方法,该方法会在cookie中写入加密后的数据,并返回Html标签代码。该标签代码会写入到页面中。

        public static HtmlString GetHtml()
        {
            if (HttpContext.Current == null)
            {
                throw new ArgumentException(WebPageResources.HttpContextUnavailable);
            }

            TagBuilder retVal = _worker.GetFormInputElement(new HttpContextWrapper(HttpContext.Current));
            return retVal.ToHtmlString(TagRenderMode.SelfClosing);
        }

2)在GetFormInputElement方法中,首先通过GetCookieTokenNoThrow方法获取Cookie中AntiForgeryToken对象(第一访问页面该对象为空)。再通过Get

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值