让ASP.NET接受有“潜在危险”的提交

什么是有“潜在危险”的提交?马上动手写个简单的例子:

用Visual Studio创建一个空白的ASP.NET MVC程序,一切默认即可,添加一个空白的HomeController,增加一个Index Action及一个Index View,View也可以暂时留空白,运行这个程序,一切都没毛病,好,现在在地址栏上敲入: http://localhost:37538/%3Cscript%3E

出现:

“从客户端中检测到有潜在危险的Request.Path值”,当然了,你还可以在地址栏上尝试点别的,比如一些特殊符号,也可能出现这种情况,注意一下,现在出现的异常为:HttpException。

现在我们尝试别的情况,改一下Controller:

    public class HomeController : Controller {
        public ActionResult Index() {
            return View();
        }
        [HttpPost]
        public ActionResult Index(string p1) {
            ViewBag.P1 = p1;
            return View();
        }
    }

再改一下View:

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <div>
        <p>@ViewBag.P1</p>
        <form method="post">
            <input type="text" name="p1" />
            <input type="submit" />
        </form>
    </div>
</body>
</html>

代码很简单,我们尝试给p1写点值,然后回显,输入个什么“123”或者“abc”是没问题的,但如果尝试输入“<a>”或者“<script>”之类的,就会出现:


“从客户端中检测到有潜在危险的Request.Form值”,和之前的出错提示有些类似,但也有显著不同,注意看,现在的Exception变成了HttpRequestValidationException,而不是之前的HttpException了。

还有另一种可以导致这个错误出现的方法,现在改一下Controller为:

    public class HomeController : Controller {
        public ActionResult Index() {
            return View();
        }
        [HttpPost]
        public ActionResult Index(string p1) {
            string p2 = Request.QueryString["p2"];
            ViewBag.P1 = p1;
            ViewBag.P2 = p2;
            return View();
        }
    }

View也改一下:

<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>Index</title>
</head>
<body>
    <div>
        <p>@ViewBag.P1</p>
        <p>@ViewBag.P2</p>
        <form method="post">
            <input type="text" name="p1" />
            <input type="submit" />
        </form>
    </div>
</body>
</html>

运行,地址栏上敲入:http://localhost:37538/Home/Index?p2=%3Cscript%3E

嗯?竟然没有报错!接着直接点页面上的“提交”按钮,这次报错了。出错提示差不多,我不再截图,大致出错文本信息为:“从客户端中检测到有潜在危险的 Request.QueryString 值”,Exception类型为HttpRequestValidationException。

另外,对于传统的Web Form,(还记得aspx吗?同学们),也是会出现这个异常的,你随便建一个叫“WebForm1.aspx”的页面,然后地址栏上敲:http://localhost:37538/WebForm1.aspx?p1=%3Cscript%3E

看吧,错误是一样的。

总结一下:

1,如果URL的路径(不包括参数)中带有“潜在危险”,那么打开页面时候会直接报错,Exception类型为HttpException

2,如果URL参数或者Post的表单数据中含有“潜在危险”,那Exception会发生在我们尝试去获得“潜在危险”的时候,Exception类型为HttpRequestValidationException

这是ASP.NET的默认行为,主要是为了防止XSS,也就是跨站脚本攻击,关于XSS的文章很多,如需进一步了解请自行Google。虽然这个报错看起来是一种好意,但这个情我不太想领,因为这个Yellow Dead Page十分不友好,另外,如果我们确实用得到这样的“潜在危险”数据呢?比如我们做一个论坛,允许用户使用一些HTML标签来格式化他们的输入,这样接受“潜在危险”就变成了必须了。我们现在来改变一下ASP.NET的默认行为,让它不再抛出这样的异常。很简单,我们来修一下web.config:

  <system.web>
    <httpRuntime requestPathInvalidCharacters="" requestValidationMode="2.0" />  <!--避免了URL路径的检查-->
    <pages validateRequest="false"></pages>  <!--避免了aspx页面对URL参数及表单数据的检查-->
  </system.web>

但我们如今一般都很少用Web Form了,大家都MVC了对吧?对于ASP.NET MVC,还需要加一个全局过滤器,来避免其对URL参数及表单数据的检查,在Application_Start()中加入:

GlobalFilters.Filters.Add(new ValidateInputAttribute(false));

ALL DONE!

没有了“潜在危险”检查,假如危险真的来临了,那可怎么办?你是说XSS吗?一般情况下,如果你不需要像论坛那样让允许用户提交“富文本”的话,直接用HTML Encode来呈现数据就肯定不会有XSS问题啊,用户尝试提交一段JavaScript,你用HTML Encode了之后,提交啥,就直接在页面上显示啥,也没啥好担心的,使用到@Html.Raw的时候就要格外小心一些,差不多就OK了。但如果你真的需要允许客户提交富文本的话,情况就变得有些复杂了,有以下解决方案来避免XSS:

1,自行检查提交内容,如果发现<script>标签之类的,拒绝提交;

2,使用HTML Parser,尝试找到“潜在危险”并将它们移除;

3,不用HTML标签,改用Markdown;

第一种方案很容易想得到,并且要做也不难,但要做得好就很难,你考虑一下以下的情况:

<a href="javascript: danger();">danger</a>
<p onclick="danger();">danger</p>
<div style="width: expression(danger());">danger</div>

看吧,防不胜防,还有各种不同的标签哦,各种onXXX事件,一些更高明的嵌套手法,唉,想做好是很难的了,这种方法不推荐!

第二种方法可以考虑使用HtmlAgilityPack这个库,用它来解释客户端提交上来的内容,一个个Tag去遍历。我建议使用“白名单”机制,只允许有限的tag,比如<a>,<p>,<div>,<ul>,<ol>,<li>等,遇到不认识的一律移除,这些标签里,也只允许有限的属性,遇到诸如“onXXX”这种不在白名单里的属性一律移除,这样就差不多了,还剩下一个比较麻烦的就是<a>标签的href属性,这个得做点特殊处理,自己判断一下这里边是否有潜在的危险,我的做法是:

    static readonly Regex _regexIsSafe = new Regex("^([a-z][a-z,0-9]*):");
    static bool IsLegalLink(string link) {
        link = link.Trim().ToLower();
        Match match = _regexIsSafe.Match(link);
        if (match.Success) {
            string schema = match.Groups[1].Value;
            if (!"http".Equals(schema) && !"https".Equals(schema)) {
                return false;
            }
        }
        return true;
    }

这样应该差不多了。或者更绝的做法就是干脆把<a>标签从白名单里移除。

这个移除潜在危险代码的过程有个专业术语叫“Sanitize”,直译的话就是“消毒”,嗯,挺形象的。

第三种方法是最为彻底的和先进的方法,但由于我没做过,所以暂时就不在这里展开了,建议大家去找找Markdown的解决方案,祝你好运!

时间: 2024-12-17 21:15:48

让ASP.NET接受有“潜在危险”的提交的相关文章

Asp.net 从客户端中检测到有潜在危险的Request.Form值

解决方法: 在Web.config文件里找到<httpRuntime>节点,然后修改requestValidationMode="2.0" 修改结果如下: <system.web> <httpRuntime targetFramework="4.5" requestValidationMode="2.0"/> <system.web> 如果是asp.net应用程序 <% @ Page Vali

解决asp.net中“从客户端中检测到有潜在危险的Request.Form值”的问题

在提交表单时候,asp.net 提示:"从客户端(......)中检测到有潜在危险的 Request.Form 值" .asp.net中的请求验证特性提供了某一等级的保护措施防止XSS攻击,asp.net的请求验证是默认启动的.这个给出各个版本.net的解决方法.asp.net 2.0 通常解决办法方案一:将.aspx文件中的page项添加ValidateRequest="false" ,如下:<%@ Page ValidateRequest="fa

asp.net mvc 客户端(&amp;)中检测到有潜在危险的 Request.Path 值。

出现这个错误后,试过 <pages validateRequest="false"> <httpRuntime requestValidationMode="2.0"/> [ValidateInput(false)] 都不ok,经测试只用以下配置就ok了 <httpRuntime requestPathInvalidCharacters="" /> MSDN解释:在请求路径中无效的字符的列表以逗号分隔). 以下

ASP.NET MVC从客户端中检测到有潜在危险的 Request.Form 值

ASP.NET MVC4(Razor)从客户端中检测到有潜在危险的 Request.Form 值 “/”应用程序中的服务器错误. 从客户端(Content=" sdfdddd ...")中检测到有潜在危险的 Request.Form 值. 说明: ASP.NET 在请求中检测到包含潜在危险的数据,因为它可能包括 HTML 标记或脚本.该数据可能表示存在危及应用程序安全的尝试,如跨站点脚本攻击.如果此类型的输入适用于您的应用程序,则可包括明确允许的网页中的代码.有关详细信息,请参阅 ht

Asp.net mvc3的“从客户端中检测到有潜在危险的 Request.Form 值”问题解决

Asp.net mvc3的“从客户端(content_v=\",<p>\n\t<imgalt=\"\" src...\")中检测到有潜在危险的Request.Form 值”解决 在三个地方修改 1.     在Controller调用的方法上添加[ValidateInput(false)] [ValidateInput(false)] ublic ActionResult EventSave() 2.在对应的asp.net web页面上加上Vali

ASP.NET检测到有潜在危险的 Request.Form 值解决方案

ASP.NET检测到有潜在危险的 Request.Form 值解决方案 ????当我们在网站中使用CKEditor等富文本编辑器时,大多都会遇到这样的到警告 这是因为ASP.NET默认开启对页面提交内容的验证(不仅是ASP.NET MVC,WebForms也默认启用对页面提交的内容进行验证),解决这个问题的关键就在于在有富文本编辑器的页面或者会有提交html代码的页面关闭验证,可大致分为以下三种情况: 基于Framework2.0 webForm的网站 这种情况相比之下算是最好解决的,直接在需要

检测到有潜在危险的 Request.Form 值。 说明: ASP.NET 在请求中检测到包含潜在危险的数据

在请求方法的顶部添加        [ValidateInput(false)]就OK了 从客户端(Content=" sdfdddd ...")中检测到有潜在危险的 Request.Form 值. 说明: ASP.NET 在请求中检测到包含潜在危险的数据,因为它可能包括 HTML 标记或脚本.该数据可能表示存在危及应用程序安全的尝试,如跨站点脚本攻击.如果此类型的输入适用于您的应用程序,则可包括明确允许的网页中的代码.有关详细信息,请参阅 http://go.microsoft.co

ASP.NET 4.0 设定 了 validateRequest="false" 仍然会出现 具有潜在危险 Request.QueryString 的错误消息

摘要:ASP.NET 4.0 设定 了 validateRequest="false" 仍然会出现 具有潜在危险Request.QueryString的错误消息 微软的asp.net网页都会默认进行Request Validation,但若是想规避这样的内建行为.(建议仍要有其他的方法来防范XSS攻击) 通常我们可以在.aspx中的Page Tag设定: ? 或是直接对整个站台设定Web.Config中??下设定全域的 不过,假如你现在在ASP.NET 4.0 的环境下的话,就算进行上

ASP.NET MVC4(Razor)从客户端中检测到有潜在危险的 Request.Form 值

说明: 请求验证过程检测到有潜在危险的客户端输入值,对请求的处理已经中止. 该值可能指示存在危及应用程序安全的尝试,如跨站点脚本攻击.若要允许页面重写应用程序请求验证设置,请将 httpRuntime 配置节中的 requestValidationMode 特性设置为 requestValidationMode="2.0".示例: <httpRuntime requestValidationMode="2.0" />.设置此值后,可通过在 Page 指令