1:Form提交模式
在使用Form提交时,MVC框架提供了一个默认的机制。如果数据中含有恶意字,则会自动转向出错页面。
2:Ajax+JSON提交模式。
MVC框架未提供对于Json数据的AntiXSS支持,所以必须自行实现。
Step1:定义一个Attribute[AllowHtml],如果有这个标记,则说明该属性允许Html,不需要验证。
/// <summary>
/// 用于标记某个属性是否允许html字符
/// </summary>
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
public sealed class AllowHtmlAttribute : Attribute
{
}
Step2:元数据解析的时候,动态设定标记为AllowHtml的属性不激发验证。
public class CustomModelMetadataProvider : DataAnnotationsModelMetadataProvider
{
public CustomModelMetadataProvider()
{
}
protected override ModelMetadata CreateMetadata(IEnumerable<Attribute> attributes, Type containerType,
Func<object> modelAccessor, Type modelType, string propertyName)
{
var metadata = base.CreateMetadata(attributes, containerType, modelAccessor, modelType, propertyName);
if (containerType == null || propertyName == null)
return metadata;
foreach (Attribute attr in attributes)
{
if (attr is AllowHtmlAttribute)
{
metadata.RequestValidationEnabled = false;
break;
}
}
}
}
Step3:实现自定义ModerBinder,拦截所有的json数据,进行anti-xss验证。
/// <summary>
/// 检测Json数据中含有恶意字符,抛出HttpRequestValidationException
/// </summary>
public class AntiXssModelBinder : DefaultModelBinder
{
protected override bool OnPropertyValidating(ControllerContext controllerContext, ModelBindingContext bindingContext, System.ComponentModel.PropertyDescriptor propertyDescriptor, object value)
{
if (controllerContext.HttpContext.Request.ContentType.StartsWith("application/json", StringComparison.OrdinalIgnoreCase))
{
int index;
if (controllerContext.Controller.ValidateRequest
&& bindingContext.PropertyMetadata[propertyDescriptor.Name].RequestValidationEnabled)
{
if (value is string)
{
if (AntiXssStringHelper.IsDangerousString(value.ToString(), out index))
{
throw new HttpRequestValidationException("Dangerous Input Detected");
}
}
else if (value is IEnumerable)
{
// 字符串数组或者集合,或者Dictionary<string, string>
// Dictionary的Key, Value会ToString后一起验证
foreach (object obj in value as IEnumerable)
{
if (obj != null)
{
if (AntiXssStringHelper.IsDangerousString(obj.ToString(), out index))
{
throw new HttpRequestValidationException("Dangerous Input Detected");
}
}
}
}
}
}
return base.OnPropertyValidating(controllerContext, bindingContext, propertyDescriptor, value);
}
}
/// <summary>
/// 检测绑定的单值字符串是否包含恶意字符
/// </summary>
public class AntiXssRawModelBinder : StringTrimModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var value = base.BindModel(controllerContext, bindingContext);
if (value is string)
{
var result = (value as string).Trim();
int index;
if (AntiXssStringHelper.IsDangerousString(value.ToString(), out index))
{
throw new HttpRequestValidationException("Dangerous Input Detected");
}
}
return value;
}
}
}
Step4:在Web站点启动的时候,配置MVC框架
RouteTableRegister.RegisterRoutes(_routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
ModelMetadataProviders.Current = new CustomModelMetadataProvider();
ModelBinders.Binders.DefaultBinder = new AntiXssModelBinder();
举例:
[Required]
[AllowHtml]
public string UserName{get;set;}
[Required]
public string Password{get;set;}
注意:这时通过JSON传过来的数据Password就会报错,而UserName则不会。
如果Ajax传入的JSON是封装好的对象,最好也要经过封装,以下为例:
public ActionResult Login(LoginModel model,[ModelBinder(typeof(AntiXssRawModelBinder))])
{
}
//AntiXssRawModelBinder核心代码
/// <summary>
/// 检测绑定的单值字符串是否包含恶意字符
/// </summary>
public class AntiXssRawModelBinder : StringTrimModelBinder
{
public override object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var value = base.BindModel(controllerContext, bindingContext);
if (value is string)
{
var result = (value as string).Trim();
int index;
if (AntiXssStringHelper.IsDangerousString(value.ToString(), out index))
{
throw new HttpRequestValidationException("Dangerous Input Detected");
}
}
return value;
}
}
如果某些参数需要支持部分HTML代码,可以采取先将该参数设置为[AllowHTML],值传到Action时,再进行手动过滤,或者 使用AntiXSS库进行编码(微软提供的AntiXSSLibrary类库)。
整理网络文章,如有错误,敬请指正,非常感谢!
- ASP.NET MVC 多语言方案
前言: 好多年没写文章了,工作很忙,天天加班, 每天都相信不用多久,就会升职加薪,当上总经理,出任CEO,迎娶白富美,走上人生巅峰,想想还有点小激动~~~~ 直到后来发生了邮箱事件,我竟然忘了给邮箱密 ...
- 全面解析ASP.NET MVC模块化架构方案
什么叫架构?揭开架构神秘的面纱,无非就是:分层+模块化.任意复杂的架构,你也会发现架构师也就做了这两件事. 本文将会全面的介绍我们团队在模块化设计方面取得的经验.之所以加了“全面”二字,是因为本文的内 ...
- asp.net MVC 3多语言方案--再次写, 配源码
之前写了一篇asp.net MVC多语言方案,那次其实是为American Express银行开发的.有许多都是刚开始接触,对其也不太熟悉.现在再回过头去看,自己做一个小网站,完全用asp.net m ...
- ASP.NET安全[开发ASP.NET MVC应用程序时值得注意的安全问题](转)
概述 安全在web领域是一个永远都不会过时的话题,今天我们就来看一看一些在开发ASP.NET MVC应用程序时一些值得我们注意的安全问题.本篇主要包括以下几个内容 : 认证 授权 XSS跨站脚本攻击 ...
- (转)asp.net mvc 开发环境下需要注意的安全问题(一)
概述 安全在web领域是一个永远都不会过时的话题,今天我们就来看一看一些在开发ASP.NET MVC应用程序时一些值得我们注意的安全问题.本篇主要包括以下几个内容 : 认证 授权 XSS跨站脚本攻击 ...
- 深入理解ASP.NET MVC(2)
系列目录 请求是如何进入MVC框架的(inbound) 当一个URL请求到来时,系统调用一个注册的IHttpModules:UrlRoutingModule,它将完成如下工作: 一.在RouteTab ...
- Asp.net Mvc中利用ValidationAttribute实现xss过滤
在网站开发中,需要注意的一个问题就是防范XSS攻击,Asp.net mvc中已经自动为我们提供了这个功能.用户提交数据时时,在生成Action参数的过程中asp.net会对用户提交的数据进行验证,一旦 ...
- ASP.NET MVC异常处理方案
异常处理是每一个系统都必须要有的功能,尤其对于Web系统而言,简单.统一的异常处理模式尤为重要,当打算使用ASP.NET MVC来做项目时,第一个数据录入页面就遇到了这个问题. 在之前的ASP.NET ...
- 微冷的雨ASP.NET MVC之葵花宝典(MVC)
微冷的雨ASP.NET MVC之葵花宝典 By:微冷的雨 第一章 ASP.NET MVC的请求和处理机制. 在MVC中: 01.所有的请求都要归结到控制器(Controller)上. 02.约定优于配 ...
- [转]ASP.NET MVC 4 最佳实践宝典
原文:http://www.cnblogs.com/sonykings/archive/2013/05/30/3107531.html ASP.NET MVC最佳实践 本文档提供了一套旨在帮助创建最佳 ...
随机推荐
- C#4.0泛型的协变,逆变深入剖析
C#4.0中有一个新特性:协变与逆变.可能很多人在开发过程中不常用到,但是深入的了解他们,肯定是有好处的. 协变和逆变体现在泛型的接口和委托上面,也就是对泛型参数的声明,可以声明为协变,或者逆变.什么 ...
- svn 常用命令总结
svn 命令篇 svn pget svn:ignore // 查看忽略项 svn commit -m "提交说明" // 提交修改 svn up(update) // 获取最新版本 ...
- .NET平台开源项目速览(17)FluentConsole让你的控制台酷起来
从该系列的第一篇文章 .NET平台开源项目速览(1)SharpConfig配置文件读写组件 开始,不知不觉已经到第17篇了.每一次我们都是介绍一个小巧甚至微不足道的.NET平台的开源软件,或者学习,或 ...
- .NET Core采用的全新配置系统[10]: 配置的同步机制是如何实现的?
配置的同步涉及到两个方面:第一,对原始的配置文件实施监控并在其发生变化之后从新加载配置:第二,配置重新加载之后及时通知应用程序进而使后者能够使用最新的配置.要了解配置同步机制的实现原理,先得从认识一个 ...
- nodejs中获取时间戳、时间差
Nodejs中获取时间戳的方法有很多种,例如: new Date().getTime() Date.now() process.uptime() process.hrtime() 平时想获取一个时间戳 ...
- Gradle 实现 Android 多渠道定制化打包
Gradle 实现 Android 多渠道定制化打包 版权声明:本文为博主原创文章,未经博主允许不得转载. 最近在项目中遇到需要实现 Apk 多渠道.定制化打包, Google .百度查找了一些资料, ...
- 年度巨献-WPF项目开发过程中WPF小知识点汇总(原创+摘抄)
WPF中Style的使用 Styel在英文中解释为”样式“,在Web开发中,css为层叠样式表,自从.net3.0推出WPF以来,WPF也有样式一说,通过设置样式,使其WPF控件外观更加美化同时减少了 ...
- BlockingCollection使用
BlockingCollection是一个线程安全的生产者-消费者集合. 代码 public class BlockingTest { BlockingCollection<int> bc ...
- 集成基于OAuth协议的单点登陆
在之前的一篇文章中,我们已经介绍了如何为一个应用添加对CAS协议的支持,进而使得我们的应用可以与所有基于CAS协议的单点登陆服务通讯.但是现在的单点登陆服务实际上并不全是通过实现CAS协议来完成的.例 ...
- Maven实战:Maven生命周期
前言 之前有写过一篇文章Maven实战,介绍了Maven的一些基本概念,以及对于一个初学者而言的Maven基础知识,当时在我看来掌握了这些基本是够用的. 随着工作的深入,越来越感觉对于Maven的理解 ...