CSRF防御之ASP.NET MVC
MVC中的Html.AntiForgeryToken()是用来防止跨站请求伪造(CSRF:Cross-site request forgery)攻击的一个措施。
举个简单例子,譬如整个系统的公告在网站首页显示,而这个公告是从后台提交的,我用最简单的写法:
网站后台(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 ...>,或者两个值不相等,就会抛出异常。
使用该方法的缺点是:
1. 这种方法是依赖于 cookie的,如果客户端禁止了 cookie ,那么这种防范就会失效。
2. 该方法是对 post请求有效,对 Get 请求无效
3. 对于 AJAX请求,MVC 框架不会自动传递 cookie和隐藏域。需要自己实现传输和读取。
CSRF防御之ASP.NET MVC的更多相关文章
- CSRF in asp.net mvc and ap.net core
如果在方法上添加了[ValidateAntiForgeryToken],没处理好 请求没有带参数 2019-09-17 14:02:45,142 ERROR [36]: System.Web.Mvc. ...
- ASP.NET MVC中防止跨站请求攻击(CSRF)
转载 http://kevintsengtw.blogspot.co.nz/2013/01/aspnet-mvc-validateantiforgerytoken.html 在 ASP.NET M ...
- ASP.Net MVC 5 高级编程 第7章 成员资格、授权和安全性
第7章 成员资格.授权和安全性 7.1 安全性 ASP.NET MVC 提供了许多内置的保护机制(默认利用 HTML 辅助方法和Razor 语法进行 HTML编码以及请求验证等功能特性,以及通过基架构 ...
- [引]ASP.NET MVC 4 Content Map
本文转自:http://msdn.microsoft.com/en-us/library/gg416514(v=vs.108).aspx The Model-View-Controller (MVC) ...
- ASP.NET MVC防范CSRF最佳实践
XSS与CSRF 哈哈,有点标题党,但我保证这篇文章跟别的不太一样. 我认为,网站安全的基础有三块: 防范中间人攻击 防范XSS 防范CSRF 注意,我讲的是基础,如果更高级点的话可以考虑防范机器人刷 ...
- Asp.net MVC 3 防止 Cross-Site Request Forgery (CSRF)原理及扩展 安全 注入
原理:http://blog.csdn.net/cpytiger/article/details/8781457 原文地址:http://www.cnblogs.com/wintersun/archi ...
- Asp.net MVC 如何防止CSRF攻击
什么是CSRF攻击? CSRF(Cross-site request forgery跨站请求伪造,也被称成为"one click attack"或者session riding,通 ...
- ASP.NET MVC 防止CSRF攻击
简介 MVC中的Html.AntiForgeryToken()是用来防止跨站请求伪造(CSRF:Cross-site request forgery)攻击的一个措施,它跟XSS(XSS又叫CSS:Cr ...
- 如何在asp.net mvc框架及django框架下面避免CSRF
CSRF 跨站伪造请求 不知CSRF为何物的,可以问下G哥. 在Asp.net MVC平台下,提供了Html.AntiForgeryToken() 方法,我们只需把其放在form的标签内,在浏览器端就 ...
随机推荐
- [问题解决]安装 SQL Server 无法开启NetFx3.5 的错误
谷歌了一下,该问题是由于系统中缺少.Net3.5相关特性造成的.需要手动安装一下3.5的环境 解决办法: Windows 徽标键+R打开运行窗口 输入Dism /online /enable-feat ...
- tomcat4 请求的处理——初步分析
以tomcat4为例, 每当HttpConnector的ServerSocket得到客户端的连接时,会创建一个Socket. 接下来就处理这个Socket发来的数据. 怎么处理呢? 考虑到客户端同时发 ...
- JavaScript-分支语句练习
-1.方程 ax^2+bx+c=0,一元二次方程求根情况. 解: <head><meta http-equiv="Content-Type" content=&q ...
- MVVM架构~knockoutjs实现简单的购物车
返回目录 概念相关 购物车相信大家都用过,很方便,可以将多个商品添加到购物车,并且可以修改购买商品的数据,当然为了用户体验好,在修改数据时,你的价格也会出现变化的,这使用JS可以实现,但我认为,代码量 ...
- javascript里阻止事件冒泡
如下图所示,灰色块包含红色块,假设我们为灰色和红色块各绑定一个单击弹框事件,当我们点击红色块时,不希望触发灰色块的弹框事件,这就需要阻止冒泡事件了. IE里阻止冒泡事件使用cancelBubble属性 ...
- 转【】浅谈sql中的in与not in,exists与not exists的区别_
浅谈sql中的in与not in,exists与not exists的区别 1.in和exists in是把外表和内表作hash连接,而exists是对外表作loop循环,每次loop循环再对内表 ...
- cordovas禁止横屏
cordovas禁止横屏 官网 http://cordova.apache.org/docs/en/latest/config_ref/index.html#preference 配置config.x ...
- 在 xampp 环境下安装 laravel
网上搜了很多教程,很多都是采用命令行安装的.但是对于web前端来说,根本就不知道在干吗! 于是,打算写一篇文章,来教后面的人如何在 XAMPP 环境下安装 laravel. 初步认识 XAMPP(Ap ...
- MongoDB更新文档
说明:来看一下关系型数据库的update语句 UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某 其中where子句就类似查询文本,定位要更改的子表,set子句类似于修改器,更 ...
- 贪心算法-Huffman编码
伪代码: 例子: