MVC 3.0学习笔记(防止跨站点请求伪造 (CSRF) 攻击)

来源:互联网 发布:淘宝店铺手机端 编辑:程序博客网 时间:2024/06/07 17:04

什么是CSRF攻击

      

CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF。

因为在ASP.NET程序中,我们的用户信息都是存在与cookies里面的,此时在用户自己来说,程序已经可以算是裸奔了。正因为如此,Web程序接受的正常客户端请求一般来自用户的点击链接和表单提交等行为。可是恶意攻击者却可以依靠脚本和浏览器的安全缺陷来劫持客户端会话、伪造客户端请求。攻击者盗用了你的身份,以你的名义发送恶意请求,以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。这就是CSRF攻击。

CSRF漏洞的攻击一般分为站内和站外两种类型:

CSRF站内类型的漏洞在一定程度上是由于程序员滥用$_REQUEST类变量造成的,一些敏感的操作本来是要求用户从表单提交发起POST请求传参给程序,但是由于使用了$_REQUEST等变量,程序也接收GET请求传参,这样就给攻击者使用CSRF攻击创造了条件,一般攻击者只要把预测好的请求参数放在站内一个贴子或者留言的图片链接里,受害者浏览了这样的页面就会被强迫发起请求。

CSRF站外类型的漏洞其实就是传统意义上的外部提交数据问题,一般程序员会考虑给一些留言评论等的表单加上水印以防止SPAM问题,但是为了用户的体验性,一些操作可能没有做任何限制,所以攻击者可以先预测好请求的参数,在站外的Web页面里编写javascript脚本伪造文件请求或和自动提交的表单来实现GET、POST请求,用户在会话状态下点击链接访问站外的Web页面,客户端就被强迫发起请求。

浏览器的安全缺陷

现在的Web应用程序几乎都是使用Cookie来识别用户身份以及保存会话状态,但是所有的浏览器在最初加入Cookie功能时并没有考虑安全因素,从WEB页面产生的文件请求都会带上COOKIE

       

MVC中防止CSRF攻击

       

使用AntiForgeryToken令牌,在ASP.NET的核心中为我们提供了一个用来检测和组织CSRF攻击的令牌。

只要在Html表单里面使用了@Html.AntiForgeryToken()就可以阻止CSRF攻击。

复制代码
@model MvcApplication.Models.Person@{    ViewBag.Title = "修改人员";    Layout = "~/Views/Shared/_Layout.cshtml";}<h2>    修改人员</h2><script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"></script><script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>@using (Html.BeginForm()){    @Html.AntiForgeryToken()    @Html.ValidationSummary(true)    <fieldset>        <legend>人员信息</legend>        @Html.HiddenFor(model => model.ID)        <div class="editor-label">            @Html.LabelFor(model => model.Name)        </div>        <div class="editor-field">            @Html.EditorFor(model => model.Name)            @Html.ValidationMessageFor(model => model.Name)        </div>        <div class="editor-label">            @Html.LabelFor(model => model.Age)        </div>        <div class="editor-field">            @Html.EditorFor(model => model.Age)            @Html.ValidationMessageFor(model => model.Age)        </div>        <p>            <input type="submit" value="保存" />        </p>    </fieldset>}<div>    @Html.ActionLink("返回列表", "Index")</div>
复制代码

  

相应的我们要在Controller中也要加入[ValidateAntiForgeryToken]过滤特性。

该特性表示检测服务器请求是否被篡改。

注意:该特性只能用于post请求,get请求无效。

复制代码
        //修改方法        // POST: /Person/Edit/5        [ValidateAntiForgeryToken]        [HttpPost]        public ActionResult Edit(int id, Person person)        {            try            {                // 数据库操作代码                return RedirectToAction("Success",person);            }            catch            {                return View();            }        }
复制代码

  

运行效果和上面的一样

然后我们在运行刚才保存的Html文件看看

哈哈报错了。。那就证明我们现在的阻止CSRF攻击是有效的。

       

使用Salt值加强保护

     

为了保证我们的AntiForgeryToken阻止在程序中唯一,更好的加密AntiForgeryToken,我们可以为AntiForgeryToken设置Salt值。

这样,即使攻击者设法得到了令牌,但是如果Salt值不匹配也不能进行post操作。

复制代码
        //修改方法        // POST: /Person/Edit/5        [ValidateAntiForgeryToken(Salt = "aa")]        [HttpPost]        public ActionResult Edit(int id, Person person)        {            try            {                // 数据库操作代码                return RedirectToAction("Success",person);            }            catch            {                return View();            }        }
复制代码

  

我们暂时不修改View代码

运行看看

可以看到加入Salt值后即使是MVC程序本身的页面都无法请求,更别说攻击者了,除非他能猜到我们的Salt值。

我们修改view代码

    @Html.AntiForgeryToken("aa")

  

继续运行项目

可以看到在view中加入Salt值后,阻止就变的有目的性了。

 

原创粉丝点击