从客户端&中检测到潜在危险的Request.Path值

问题描述

|| 我知道为什么会这样,但是我需要解决方法。我在StackOverflow上调查了其他一些问题,但是这些问题都没有帮助。我不想在整个网站上禁用输入验证,因为这绝对是危险的。我只有一个地方(至少到目前为止)需要禁用输入验证。 我用[ValidateInput(false)]属性装饰了Action Method,然后用Html.Encode对字符串进行编码。但是,我仍然遇到相同的错误。这是我的观点:
<div id=\"sharwe-categories\">
    <ul class=\"menu menu-vertical menu-accordion\">
        @foreach(var topLevel in Model)
        {
            var topLevelName = Html.Encode(topLevel.Name);
             <li class=\"topLevel\">
                <h3>  
                    @Html.ActionLink(topLevel.Name,\"Index\",\"Item\",new { category = topLevelName },new {@class = \"main\"} )
                    <a href=\"#\" class=\"drop-down\"></a>
                </h3>
                <ul>
                    @foreach (var childCategory in topLevel.Children)
                    {
                        var childcategoryName = Html.Encode(childCategory.Name);
                        <li>@Html.ActionLink(childCategory.Name,new RouteValueDictionary { { \"category\",topLevelName },{ \"subcategory\",childcategoryName } },null)</li>
                    }
                </ul>
            </li>
        }

    </ul>

</div>
如您所见,没有用户输入。但是某些类别名称中有一些“危险”字符...有解决方案吗?     

解决方法

尽管Darin的答案是完全可行的,但我不建议您使用Scott Hanselman的技术来逐步关闭所有这些验证。你迟早会陷入深渊... 第二种建议是将ID与伪字符串(对于SEO和人员非常有用)一起使用是一种可行的方法,但是有时它们也不可行。想象一下这个请求URL:
/111/Electronics/222/Computers/333/Apple
尽管我们将拥有这些ID,我们也可以依靠这些ID以及对人/ SEO友好的类别名称,但这绝对是不希望的。当我们需要表示一个项目时,ID +虚拟字符串是可行的。在其他情况下则不是。而且由于必须显示类别和子类别,所以这是一个问题。 所以,你可以做什么? 两种可能的解决方案: 清理类别名称只包含有效字符-可以这样做,但是如果这些不是静态的并且不能由特权用户编辑,则您在这里很不走运,因为即使您现在已经清理了它们,也会有人输入内容以后无效 随时随地清理字符串-使用类别名称时,请清理它,在阅读和使用它时(以获得实际的类别ID),您可以将提供的(先前清理过的)类别名称与您要清理的数据库中的值进行比较苍蝇: 现在,同时过滤类别 在生成类别名称之前 我建议您采用2.2方法。扩展数据库表以使其具有两列: 类别显示名称 类别URL友好名称 您还可以在第二列上设置唯一约束,这样就不会发生两个类别(即使它们的显示名称不同)具有相同的URL友好名称的情况。 如何清洁 首先想到的是去除无效字符,但这很繁琐,您很可能会遗漏一些东西。从类别显示名称中获取有效字符更加容易和明智。生成虚拟URL类别名称时,我做过同样的事情。只需拿出有效的东西,然后将其余的东西分类即可。它通常可以正常工作。这样的正则表达式的两个示例:
(\\w{2,})
-仅使用字母,数字和下划线,并且至少使用其中的两个(因此,我们省略了一个或单个数字以及类似的数字,这些数字不会增加任何含义,并且会不必要地延长我们的网址
([a-zA-Z0-9]{2,})
-仅字母和数字(也是2+) 获取类别显示名称中的所有匹配项,并用空格/破折号将它们加入并与原始显示名称一起保存。我的另一个问题恰恰与此有关。 为什么要增加一列?因为您无法在SQL Server中运行正则表达式。如果您使用的是MySql,则可以使用一列,也可以在数据库上使用正则表达式。     ,即使您不应该这样做,有时也没有一种简单的方法来解决它。您正在寻找web.Config中httpRuntime标记上的requestPathInvalidCharacters。只需在部分中输入以下内容:
<httpRuntime requestPathInvalidCharacters=\"&lt;,&gt;,*,%,:,\\\" />
我强烈建议您使用以下方法来锁定它:
<location path=\"the/path/you/need/to/lock/down\">
    <system.web>
        <httpRuntime requestPathInvalidCharacters=\"&lt;,\\\"/>
    </system.web>
</location>
只需将其放入根标记中即可。这样,您就不会打开整个站点以允许在路径中使用&号,并且可能会使整个站点遭受无法预料的攻击。     ,您可能会发现以下博客文章对在URL中使用特殊字符很有用。但是通常,最好的做法是将这些标题替换为与StackOverflow相同的子句,在URL中使用问题标题以获得更好的SEO,并使用ID进行标识。