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(); 
}

填写完公告,提交,显示

此时提供给了跨站***的漏洞,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()配合在对应的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中点"黑掉这个网站",就会出现

这样就防止了跨站***。

页面上的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]和<input name=antiForgeryTokenName ...>两个的值是否相同,

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

转载于:https://blog.51cto.com/haihuiwei/1966347

MVC Html.AntiForgeryToken() 防止CSRF***相关推荐

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

    (一)MVC Html.AntiForgeryToken() 防止CSRF攻击 MVC中的Html.AntiForgeryToken()是用来防止跨站请求伪造(CSRF:Cross-site requ ...

  2. mvc html.antiforgerytoken,MVC Html.AntiForgeryToken() 防止CSRF***

    MVC中的Html.AntiForgeryToken()是用来防止跨站请求伪造(CSRF:Cross-site request forgery)***的一个措施,它跟XSS(XSS又叫CSS:Cros ...

  3. 记得ajax中要带上AntiForgeryToken防止CSRF攻击

    经常看到在项目中ajax post数据到服务器不加防伪标记,造成CSRF攻击 在Asp.net Mvc里加入防伪标记很简单在表单中加入Html.AntiForgeryToken()即可. Html.A ...

  4. ajax中加上AntiForgeryToken防止CSRF攻击

    经常看到在项目中ajax post数据到服务器不加防伪标记,造成CSRF攻击 在Asp.net Mvc里加入防伪标记很简单在表单中加入Html.AntiForgeryToken()即可. Html.A ...

  5. Spring MVC,Thymeleaf,Spring Security应用程序中的CSRF保护

    跨站点请求伪造(CSRF)是一种攻击,它迫使最终用户在当前已通过身份验证的Web应用程序上执行不需要的操作. 如果您使用Spring Security 3.2及更高版本,在Spring MVC / T ...

  6. mvc学习-编辑提交需要注意-mvc重点

    示例代码: // GET: /Movies/Edit/5 public ActionResult Edit(int? id) {if (id == null){return new HttpStatu ...

  7. 初探CSRF在ASP.NET Core中的处理方式

    前言 前几天,有个朋友问我关于AntiForgeryToken问题,由于对这一块的理解也并不深入,所以就去研究了一番,梳理了一下. 在梳理之前,还需要简单了解一下背景知识. AntiForgeryTo ...

  8. Spring Security(三十六):12. Spring MVC Test Integration

    Spring Security provides comprehensive integration with Spring MVC Test Spring Security提供与Spring MVC ...

  9. Spring Security 参考手册(一)

    Spring Security 参考手册 Ben AlexLuke TaylorRob WinchGunnar Hillert Spring security 是一个强大的和高度可定制的身份验证和访问 ...

最新文章

  1. DELL服务器装2003系统
  2. 一个常用的表单文本框input输入提示
  3. Android --- 如何使状态栏和标题栏底色相同
  4. Javascript中call的使用
  5. HDU 2546(01背包)
  6. 局域网大型文件分发的可能解决方案
  7. Elasticsearch5中安装Elasticsearch-head插件
  8. mysql int tinyint_MySQL中int(M)和tinyint(M)数值类型中M值的意义
  9. careyshop-商城框架系统
  10. K8S_Google工作笔记0002---K8S介绍和特性
  11. 【转载】MySQL -- SET NAMES utf8
  12. java华氏度xhuan_华氏摄氏转换
  13. 微信小程序:蓝牙通讯,搜索、发送与接收
  14. 继 layui 之后, jQuery Mobile 宣布完全弃用!
  15. Java实现Zoho Mail 发送邮件,使用hutool工具类。
  16. 2021年秋招面经分享·地平线【芯片设计研发工程师】
  17. 寒武纪“失速”,是AI芯片行业的阵痛?
  18. POI操作EXCEL删除行
  19. EPUB阅读器聚合-Android
  20. 1626:Hankson 的趣味题

热门文章

  1. JAVA编码(41)—— 线程池队列执行任务(ThreadPoolQueue)(1)
  2. 各类排序算法实现(亲测)
  3. POJ 1195 Mobile phones【 二维树状数组 】
  4. Atitit.操作注册表 树形数据库 注册表的历史 java版本类库总结
  5. c# xmlhttp POST提取远程webservice数据
  6. 在C#中使用代理的方式触发事件 的简单习作
  7. 小贝拉机器人是朋友_报废机器人应该属于什么垃圾?《宝莱坞机器人2.0》给你答案...
  8. java如何让线程等待_如何使Java线程等待另一个线程的输出?
  9. 仓库无证如何处罚_“非现场执法”查处无证网约车,罚款15万!滴哥:怎们罚的都不知道!...
  10. c++全局监听ctrl s_号称史上最全!134个CAD快捷键强烈来袭,难道你只知道Ctrl+C?...