处理HttpRequestValidationException,拒绝简单粗暴

翅膀的初衷

发表于2013-07-19 23:47:39

在asp.net中,如果你提交的内容中含用尖括号或者其它危险字符时,程序会抛出HttpRequestValidationException异常:从客户端(****)中检测到有潜在危险的 Request.Form 值,对于这样的问题,相信每个做过web开发的.net开发者都遇到过,因为在实际开发中,我们总是避免不了要向服务器提交正常的HTML内容!

 

在.net 2.0中,我会毫不犹预的在asp.net中配置 validateRequest=false或者在web.config中配置 <pages validateRequest="false" />,然而,在4.0以上版本因为验证机扩大了范围,原有的设置已经不再起作用了,只有将httpRuntime 配置节中的 requestValidationMode 特性设置为 requestValidationMode="2.0"(如: <httpRuntime requestValidationMode="2.0" />)才能生效!

 

其实这样的问题我不是第一次遇到了,不过由于最近在4.0平台上面一直是基于MVC的开发,只需要在Controller类或action方法上面加一个ValidateInput(false)即可解决,然而这几天打算把自己的某个管理后台优化,使用静态页加大量AJAX来实现,在开发过程中,发现了一个十分诡异的问题得不到解决,只好将整个Request.Form传到另一个通用的方法中去自行处理,结果发现传参过去后,在访问到带html内容的键时,再次抛出了HttpRequestValidationException异常,以前记得可以通过重写某个验证方法来解决访问题,于是想干脆写个通用点的方法,一劳永逸的解决这个麻烦!

 

问题出现了,因为记不起需要重写的是哪个类,只能去搜索,结果在百度查询了几十条记录,然后去博客园搜了十几条记录,都是千篇一律的设置requestValidationMode="2.0"然后validateRequest="false" ,我这时的心情就像一个顽固的老学研一样,恨不得捏着胡子,摇着脑袋,然后痛心疾首的说:“简单粗暴啊,简单粗暴...”

 

在4.0中为什么扩大了验证范围?因为现在的很多攻击已经不仅限于get/post参数了,说实话,我很多年前就发现很多开发者根本不会考虑像cookie之类的东西的安全,甚至如果构建得好的话,cookie都可以进行sql注入,然后现在ASP.NET的SQL注入很难,因为大多数人都不会再使用加号去拼字符串了,但总是有些奇葩的存在,比如我们公司的技术老大,强制我们使用这种上个世纪的古老的方法来写SQL,并以规范的名义!

 

当然,在我自己私人项目中,这是永远不可能存在的(注,HttpRequestValidationException其实验证的是xss方面的攻击,并不是注入方面的攻击)!那么,为了图方便,我们又将验证方式改成2.0的模式,这是十分不可取的,过程不多说,最终于google中终于找到了这个类,重写下即解决:

 

    public class RequestValidator : System.Web.Util.RequestValidator
    {
        protected override bool IsValidRequestString(System.Web.HttpContext context, string value, System.Web.Util.RequestValidationSource requestValidationSource, string collectionKey, out int validationFailureIndex)
        {
            //我只增加了POST参数验证 
            //如果不存在POST参数,则将验证还是交给基类处理
            if (context.Request.Form.Count == 0)
            {
                return base.IsValidRequestString(context, value, requestValidationSource, collectionKey, out validationFailureIndex);
            }
            else
            {
                if (!"你的硷证代码")
                {
                    validationFailureIndex = 1;
                    return false;
                }else
                    validationFailureIndex = -1;
                    return true;
                }
                
            }
        }
    }

在web.config中加上句

<system.web> 
    <httpRuntime requestValidationType="JinianNet.Web.RequestValidator" />
 </system.web>