简介

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

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

实例

我们新建一个简单的网站发布公告界面

@{
Layout = null;
} <!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
@using (Html.BeginForm("Notice", "Home", FormMethod.Post))
{
@:网站公告:<input type="text" name="Notice" id="Notice" />
<input type="submit" value="Submit" />
}
</body>
</html>

提交后

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

(1)攻击者知道该目标站点。

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

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

比如我们现在知道发布新闻的地址:http://localhost:56874/Home/Notice

比如我们新建一个页面

@{
Layout = null;
} <!DOCTYPE html> <html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
</head>
<body>
<form action="http://localhost:56874/Home/Notice" method="post">
网站公告:<input type="text" name="Notice" id="Notice" />
<input type="submit" value="Submit" />
</form>
</body>
</html>

发起攻击

这样在网站的公告就被篡改了。作为安全性考虑,这种情况肯定不会让它发生的。

如何防止

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

修改上面提交代码

@using (Html.BeginForm("Notice", "Home", FormMethod.Post))
{
@Html.AntiForgeryToken();
@:网站公告:<input type="text" name="Notice" id="Notice" />
<input type="submit" value="Submit" />
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Notice(string Notice)
{
ViewBag.Notice = Notice;
return View();
}

再次运行网站,界面没什么变化当我们查看源代码的时候发现多了一个东西

<input name="__RequestVerificationToken" type="hidden" value="oo1kDYx6CUL3YSyZHokvWgPzOcZhZID_75tiqYBgNMBBjQNo4FgmWpO5dRsVlvqIVgZH34FvTArCFbWKuDkCbwl5UFOAxzxmaTwuQ9iBBHY1" />

现在当我们再次篡改数据的时候

我们看一下Html.AntiForgeryToken()会为当前请求,生成一个名为__RequestVerificationToken的cookie,还有一个名为__RequestVerificationToken的隐藏域。

为了验证一个来自form post请求,还需要在目标action上增加[ValidateAntiForgeryToken]特性,它是一个验证过滤器,它主要检查

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

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

Ajax如何CSRF攻击

在Asp.net Mvc里加入防伪标记很简单在表单中加入Html.AntiForgeryToken()即可。

Html.AntiForgeryToken()会生成一对加密的字符串,分别存放在Cookies 和 input 中。

我们在ajax post中也带上AntiForgeryToken

<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<script src="~/Script/jquery-1.10.2.min.js"></script>
</head>
<body>
<form>
网站公告:<input type="text" name="Notice" id="Notice" />
<input type="button" value="提交" id="btn" />
</form>
</body>
</html>
<script>
$(function () {
$("#btn").click(function () {
var token = $('@Html.AntiForgeryToken()').val();
var headers = {};
headers["__RequestVerificationToken"] = token;
$.ajax({
type: 'POST',
url: '/Home/Notice',
cache: false,
headers: headers,
data: { Notice: $("#Notice").val()},
success: function (data) {
alert(data)
},
error: function () {
alert("Error")
}
}); })
})
</script>

自定义ValidateAntiForgeryToken

public class MyValidateAntiForgeryToken: AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
var request = filterContext.HttpContext.Request;
if (request.HttpMethod== WebRequestMethods.Http.Post)
{
if (request.IsAjaxRequest())
{
var antiForgeryCookie = request.Cookies[AntiForgeryConfig.CookieName];
var cookiValue = antiForgeryCookie != null ? antiForgeryCookie.Value : null;
var s = request.Headers["__RequestVerificationToken"];
AntiForgery.Validate(cookiValue, request.Headers["__RequestVerificationToken"]);
}
else
{
new ValidateAntiForgeryTokenAttribute() .OnAuthorization(filterContext); }
}
}
}

修改HomeController Notice方法

[HttpPost]
// [ValidateAntiForgeryToken]
[MyValidateAntiForgeryToken]
public ActionResult Notice(string Notice)
{
ViewBag.Notice = Notice; return Json(new { message = Notice });
}

这样就防止了ajax post数据到服务器不加防伪标记,造成CSRF攻击

ASP.NET MVC 防止CSRF攻击的更多相关文章

  1. asp.netcore mvc 防CSRF攻击,原理介绍+代码演示+详细讲解

    一.CSRF介绍 1.CSRF是什么? CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session ridin ...

  2. ASP.NET MVC防范CSRF最佳实践

    XSS与CSRF 哈哈,有点标题党,但我保证这篇文章跟别的不太一样. 我认为,网站安全的基础有三块: 防范中间人攻击 防范XSS 防范CSRF 注意,我讲的是基础,如果更高级点的话可以考虑防范机器人刷 ...

  3. 保护ASP.NET 应用免受 CSRF 攻击

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

  4. ASP.NET MVC 防止 CSRF 的方法

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

  5. MVC防止CSRF攻击

    可能我们大多数人做web的时候不会太注意这个问题,但是这是一个很重要的一个点.我们写代码写业务的时候也应该从各方面多思考. 首先就是先简单介绍下什么是CSRF CSRF 全程是 Cross-site ...

  6. MVC 应用免受 CSRF攻击

    保护ASP.NET 应用免受 CSRF 攻击   CSRF是什么? CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack ...

  7. Spring mvc拦截器防御CSRF攻击

    CSRF(具体参考百度百科) CSRF(Cross-site request forgery跨站请求伪造,也被称为“One Click Attack”或者Session Riding,通常缩写为CSR ...

  8. [转]浅谈CSRF攻击方式

    在CSDN中看到对CSRF攻击的原理及防护文章,讲解浅显易懂,特转之: 来源:http://blog.csdn.net/fationyyk/article/details/50833620 一.CSR ...

  9. ASP.NET安全[开发ASP.NET MVC应用程序时值得注意的安全问题](转)

    概述 安全在web领域是一个永远都不会过时的话题,今天我们就来看一看一些在开发ASP.NET MVC应用程序时一些值得我们注意的安全问题.本篇主要包括以下几个内容 : 认证 授权 XSS跨站脚本攻击 ...

随机推荐

  1. 精《Linux内核精髓:精通Linux内核必会的75个绝技》一HACK #7 Cgroup、Namespace、Linux容器

    HACK #7 Cgroup.Namespace.Linux容器 本节将介绍Cgroup与Namespace以及通过这两个功能实现的容器功能.CgroupCgroup(control group)是将 ...

  2. findbug、p3c、checkstyle、sonar安装使用

    idea插件安装方式: Preferences—>Plugins—>查找插件—>Install Preferences—>Plugins—>Install plug fr ...

  3. PyDev for eclipse 插件下载地址

    PyDev for eclipse 插件下载地址http://sourceforge.net/projects/pydev/files/pydev/python解释器以及python类库下载地址htt ...

  4. unicat,multicast,broadcast区别

    单播.多播和广播单播”(Unicast).“多播”(Multicast)和“广播”(Broadcast)这三个术语都是用来描述网络节点之间通讯方式的术语.那么这些术语究竟是什么意思?区别何在? 1.单 ...

  5. 【CentOS 6.5】安装gcc-4.8.2和Qt5.2

    因为CentOS6.5中gcc版本比较低.安装Qt5.2前先升级gcc. 首先下载gcc,附上百度盘地址:http://pan.baidu.com/s/1jGibvqY 解压安装包,并进入到解压文件夹 ...

  6. jsp 学习 第1步 - 引入 jstl

    通过 eclipse 新建 动态web项目  默认是没有引入 jstl, 则无法JSP页面引入相关标记. <%@ taglib prefix="c" uri="ht ...

  7. javascript instanceof,typeof的区别

    区分string 与 String的区别 为什么结果会是false呢? <script type="text/javascript"> var aColors = [& ...

  8. leetcode73

    public class Solution { public void SetZeroes(int[,] matrix) { ); ); var listrow = new Dictionary< ...

  9. docker-compose搭建单机多节点es + kibana

    docker-compose.yml配置如下: version: '2.2' services: elasticsearch: image: docker.elastic.co/elasticsear ...

  10. Lamda所有的Capture均是引用

    [Lamda所有的Capture均是引用] 下面的程序,两个lambda 引用的实际上是同一个a.b.连int都能引用了,说明Lambda对所有类型都是以引用来处理. ; ; Func<int& ...