精选文章 MVC Html.AntiForgeryToken() 防止CSRF攻击

MVC Html.AntiForgeryToken() 防止CSRF攻击

作者:会做饭的技术男 时间: 2020-07-28 09:26:17
会做饭的技术男 2020-07-28 09:26:17

转载博客:http://blog.csdn.net/cpytiger/article/details/8781457

(一)MVC Html.AntiForgeryToken() 防止CSRF攻击

MVC中的Html.AntiForgeryToken()是用来防止跨站请求伪造(CSRF:Cross-site request forgery)攻击的一个措施,它跟XSS(XSS又叫CSS:Cross-Site-Script),攻击不同,XSS一般是利用站内信任的用户在网站内插入恶意的脚本代码进行攻击,而CSRF则是伪造成受信任用户对网站进行攻击。

举个简单例子,譬如整个系统的公告在网站首页显示,而这个公告是从后台提交的,我用最简单的写法:网站后台(Home/Index页面)设置首页公告内容,提交到HomeController的Text Action

@using (Html.BeginForm("Text","Home",FormMethod.Post))  
{  
    @:网站公告:<input type="text" name="Notice" id="Notice" />  
    <input type="submit" value="Submit" />  
}  

HomeController的Text Action

[HttpPost]  
 public ActionResult Text()  
 {  
     ViewBag.Notice = Request.Form["Notice"].ToString();  
     return View();  
 } 

填写完公告,提交,显示

MVC Html.AntiForgeryToken() 防止CSRF攻击1

此时提供给了跨站攻击的漏洞,CSRF一般依赖几个条件

(1)攻击者了解受害者所在的站点

(2)攻击者的目标站点具有持久化授权cookie或者受害者具有当前会话cookie

(3)目标站点没有对用户在网站行为的第二授权此时

具体参见http://baike.baidu.com/view/1609487.htm

现假设我知道我要攻击的网站的地址,譬如是http://localhost:6060/Home/Text,且也满足2,3的情况。

于是我新建一个AntiForgeryText.html文件,内容如下:

DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
<html xmlns="http://www.w3.org/1999/xhtml" >  
<head>  
    <title>title>  
head>  
<body>  
    <form name="badform" method="post" action="http://localhost:6060/Home/Text">  
        <input type="hidden" name="Notice" id="Notice" value="你的网站被我黑了。。" />  
        <input type="submit" value="黑掉这个网站" />  
    form>  
body>  
html>  

在这个html中加了一个隐藏的字段,Name和Id和网站要接收的参数名一样。

我点击了“黑掉这个网站”,呈现如下

MVC Html.AntiForgeryToken() 防止CSRF攻击2

这个就是利用了漏洞把首页的公告给改了,这就是一个简单的跨站攻击的例子。

MVC中通过在页面上使用 Html.AntiForgeryToken()配合在对应的Action上增加[ValidateAntiForgeryToken]特性来防止跨站攻击。

把上面的代码改成

@using (Html.BeginForm("Text","Home",FormMethod.Post))  
{  
    @Html.AntiForgeryToken()  
    @:网站公告:<input type="text" name="Notice" id="Notice" />  
  <input type="submit" value="Submit" />  
}  

对应的Action

[HttpPost]  
[ValidateAntiForgeryToken]  
public ActionResult Text()  
{  
    ViewBag.Notice = Request.Form["Notice"].ToString();  
    return View();  
}  

这样子我在AntiForgeryText.html中点"黑掉这个网站",就会出现

MVC Html.AntiForgeryToken() 防止CSRF攻击3

这样就防止了跨站攻击。

 

页面上的Html.AntiForgeryToken()会给访问者一个默认名为__RequestVerificationToken的cookie
为了验证一个来自form post,还需要在目标action上增加[ValidateAntiForgeryToken]特性,它是一个验证过滤器,
它主要检查

(1)请求的是否包含一个约定的AntiForgery名的cookie

(2)请求是否有一个Request.Form["约定的AntiForgery名"],约定的AntiForgery名的cookie和Request.Form值是否匹配

 

其中主要涉及到System.Web.WebPages.dll中的静态类AntiForgery
Html.AntiForgeryToken()调用了AntiForgery静态类的GetHtml方法,它产生一个随机值然后分别存储到客户端cookie和页面的hidden field中,

(1)Request.Cookies[antiForgeryTokenName](默认也是Request.Cookies["__RequestVerificationToken"])

(2)页面上的hiddenfield

<input name="__RequestVerificationToken" type="hidden" value="9rUlMYvsH6eMcFN9tn/wRwAG07eROraVaeTn9hHMXKkMmDbR8jLw5DKdVnZBJ9siQHeGyl1w4rSB141LnxMp2ahV0qP1lElPeukqfcUFYoxrm/EfpSJjZavykmzn15VeGFMKkmgFj5a1UFhZFaW2aZgeN38x9lt0OFSoca7eMVU=" />  

其中cookie的key的名字和页面hidden field的名字是一样的,默认都是"__RequestVerificationToken",如果有提供ApplicationPath的话,那就是由"__RequestVerificationToken"和经过处理后的ApplicationPath组成。

 

Controller端则通过在Action上增加[ValidateAntiForgeryToken]特性来验证,
ValidateAntiForgeryTokenAttribute继承了FilterAttribute和IAuthorizationFilter,通过传递匿名委托方法,

委托调用AntiForgery类的Validate方法来实现验证。

Validate方法中主要验证Request.Cookies[antiForgeryTokenName]和antiForgeryTokenName ...>两个的值是否相同,

如果页面没有antiForgeryTokenName ...>,或者两个值不相等,就会抛出异常。

(二)关于CSRF攻击及mvc中的解决方案 [ValidateAntiForgeryToken]

一.CSRF是什么?

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

二.CSRF可以做什么?

  你这可以这么理解CSRF攻击:攻击者盗用了你的身份,以你的名义发送恶意请求。CSRF能够做的事情包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账......造成的问题包括:个人隐私泄露以及财产安全。

三.CSRF漏洞现状

  CSRF这种攻击方式在2000年已经被国外的安全人员提出,但在国内,直到06年才开始被关注,08年,国内外的多个大型社区和交互网站分别爆出CSRF漏洞,如:NYTimes.com(纽约时报)、Metafilter(一个大型的BLOG网站),YouTube和百度HI......而现在,互联网上的许多站点仍对此毫无防备,以至于安全业界称CSRF为“沉睡的巨人”。

四.CSRF的原理

MVC Html.AntiForgeryToken() 防止CSRF攻击4

 

从上图可以看出,要完成一次CSRF攻击,受害者必须依次完成两个步骤:

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

  2.在不登出A的情况下,访问危险网站B。

  看到这里,你也许会说:“如果我不满足以上两个条件中的一个,我就不会受到CSRF的攻击”。是的,确实如此,但你不能保证以下情况不会发生:

  1.你不能保证你登录了一个网站后,不再打开一个tab页面并访问另外的网站。

  2.你不能保证你关闭浏览器了后,你本地的Cookie立刻过期,你上次的会话已经结束。(事实上,关闭浏览器不能结束一个会话,但大多数人都会错误的认为关闭浏览器就等于退出登录/结束会话了......)

  3.上图中所谓的攻击网站,可能是一个存在其他漏洞的可信任的经常被人访问的网站。

 

以上内容转自:http://www.cnblogs.com/hyddd/archive/2009/04/09/1432744.html

 

具体步骤:

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

2、相应的我们要在Controller中也要加入[ValidateAntiForgeryToken]过滤特性。该特性表示检测服务器请求是否被篡改。注意:该特性只能用于post请求,get请求无效。

3、至于JS,我们的项目中引用的是在JS时要使用: $.ajaxAntiForgery才行,如:

$.ajaxAntiForgery({
            type: "post",
            data: { GroupName: $("#GroupName").val(), GroupPhones: $("#GroupPhones").val() },
            dataType: "json",
            url: "/Event/Mass/AddGroup",
            success: function (data) {
                if (data) {

                    alert("添加成功 ");
                    $.unblockUI();
                }
                else {
                    alert("添加失败 ");
                }
         }
 })

注:对数据进行增删改时要防止csrf攻击!

(三)BeginFormAntiForgeryPost

Orchard1.6中,Module.txt文件中的设置AntiForgery:enable及页面中BeginFormAntiForgeryPost的作用也是一样的,不再赘述!

(四)参考网址

http://www.cnblogs.com/dragon_mail/archive/2011/07/10/2102364.html

http://blog.csdn.NET/luck901229/article/details/8261640

勿删,copyright占位
分享文章到微博
分享文章到朋友圈

上一篇:笔记 || 小程序

下一篇:STM32-单片机之DMA(Direct Memory Access,DMA)

您可能感兴趣

  • PHP面试题(个人总结)————(暂不更新)

    批批机械 1. 你为什么离职? 2. 公司在哪? 3. 在哪住? 4. 上家公司多少薪资? 5. 公司有多少人? 6. Laravel和tp框架有什么区别(扩展特性,事件机制 任务调度 数据迁移 数据填充等 ) 7. 什么是composer 8. Mysql数据库经常用到哪些命令 9. 数据库性能优化可以从哪方面考虑 10. 如何判断索引是否失效 11. Redis你知道哪些数据类型 12....

  • 最新Java面试实战

    数据库&事务 1.什么样的场景会产生数据库死锁,如何解决? 2.SQL如何优化 3.Oracle和mysql分页的实现原理 4.唯一索引能否插入空 5.数据库索引的算法原理 6.乐观锁,悲观锁 7.SQL怎样判断字段是否为空 WEB 1.post和get区别是什么? 2.cookie/session有什么区别? 3.web集群中登录态如何共享? 4.xss、csrf等如何防范? 5.sql注...

  • 前端面试题(中)

    前端面试题 HTML Doctype作用?标准模式与兼容模式各有什么区别? (1)、声明位于位于HTML文档中的第一行,处于 标签之前。告知浏览器的解析器用什么文档标准解析这个文档。DOCTYPE不存在或格式不正确会导致文档以兼容模式呈现。 (2)、标准模式的排版 和JS运作模式都是以该浏览器支持的最高标准运行。在兼容模式中,页面以宽松的向后兼容的方式显示,模拟老式浏览器的行为以...

  • 【第一篇】ASP.NET MVC快速入门之数据库操作(MVC5+EF6)

    2019独角兽企业重金招聘Python工程师标准>>> 目录 【第一篇】ASP.NET MVC快速入门之数据库操作(MVC5+EF6) 【第二篇】ASP.NET MVC快速入门之数据注解(MVC5+EF6) 【第三篇】ASP.NET MVC快速入门之安全策略(MVC5+EF6) 【第四篇】ASP.NET MVC快速入门之完整示例(MVC5+EF6) 新建项目 打开VS2015,找到菜单项[文...

  • yii2框架的详细介绍

    yii2框架的安装我们在之前文章中已经提到下面我们开始了解YII2框架 强大的YII2框架网上指南:http://www.yii-china.com/doc/detail/1.html?postid=278或者 http://www.yiichina.com/doc/guide/2.0 Yii2的应用结构: 目录篇: advance版本的特点是:根目录下预先分配了三个模块,分别是前台、后台、...

  • 关于前端

    position的值, relative和absolute分别是相对于谁进行定位的? absolute :生成绝对定位的元素, 相对于最近一级的 定位不是 static 的父元素来进行定位。 fixed (老IE不支持)生成绝对定位的元素,通常相对于浏览器窗口或 frame 进行定位。 relative 生成相对定位的元素,相对于其在普通流中的位置进行定位。 static 默认值。没有定位,...

  • web前端开发与iOS终端开发的异同

    毕业之前一直在做前端开发,毕业后就转成做iOS开发,这两者有很多挺有意思的对比,尝试写下我能想到的它们的一些相同点和不同点。 语言 前端和终端作为面向用户端的程序,有个共同特点:需要依赖用户机器的运行环境,所以开发语言基本上是没有选择的,不像后台想用什么就用什么,iOS 只能用object-c,前端只能javascript,当然iOS还可以用RubyMotion,前端还能用GWT/Coffe...

  • Mvc5+Entity Framework6 之二----在MVC中用Entity Framework实现基本的CRUD

    目标:创建控制器和视图的代码,实现CRUD(创建,读取,更新,删除)功能 创建一个详细信息页 控制器为Students的Index页生成的代码排除Enrollments属性在外,因为该属性中关联着一个集合。而该集合的内容将会在Details页面 标签中显示。 在控制器Controllers\StudentController.cs的代码中使用Find方法为Details视图取出单个Stude...

华为云40多款云服务产品0元试用活动

免费套餐,马上领取!
CSDN

CSDN

中国开发者社区CSDN (Chinese Software Developer Network) 创立于1999年,致力为中国开发者提供知识传播、在线学习、职业发展等全生命周期服务。