从客户端检测到潜在危险的 Request.Path 值 (&)
Posted
技术标签:
【中文标题】从客户端检测到潜在危险的 Request.Path 值 (&)【英文标题】:A potentially dangerous Request.Path value was detected from the client (&) 【发布时间】:2011-08-06 15:10:24 【问题描述】:我明白为什么会发生这种情况,但我需要解决方法。我在 *** 上查看了其他一些问题,但没有一个有帮助。我不想禁用整个网站的输入验证,因为这绝对是危险的。我只有一个(至少现在)需要禁用输入验证的地方。
我使用 [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, "Index", "Item", new RouteValueDictionary "category", topLevelName , "subcategory", childcategoryName , null)</li>
</ul>
</li>
</ul>
</div>
如您所见,没有用户输入。但是有些类别名称中有一些“危险”字符...有什么解决办法吗?
【问题讨论】:
你能提供导致问题的值吗? @Robert Koritnik:包含“&”或“,”或任何危险字符的值... 【参考方案1】:您可能会发现following blog post 对于在 url 中使用特殊字符很有用。但一般来说,最好的做法是 replace those titles with slugs 与 *** 一样,在 url 中使用问题标题以获得更好的 SEO 并使用 id 来识别它们。
【讨论】:
但是使用 requestValidationMode v2 并使用 [ValidateInput(false)] 装饰 Action 方法是否安全?在我的应用程序中,安全性是重中之重,所以我不能冒任何风险...... @Kassem,ValidateInput(false)
属性用于将 HTML 发布到控制器操作。在 ASP.NET MVC 3 中,您可以使用 [AllowHtml]
属性来装饰视图模型属性,该属性将仅对更安全的该属性禁用请求验证。如果您使用AllowHtml
属性,则无需设置requestValidationMode="2.0"
。如果您想将特殊字符作为 url 的一部分和您没有选择的路由参数发布,则需要遵循我链接到的博客文章中的建议。
除非他以某种方式更改类别命名...通常或仅在 URL 中使用时...
@Robert Koritnik,是的,这正是我建议的两种解决方案之一:使用蛞蝓。
是的,你做到了。我同意。但是添加了 ID,我认为这在他的情况下是不可行的,因为它有多个类别。但是,是的。你做到了。【参考方案2】:
尽管 Darin 的答案完全可行,但我不建议使用 Scott Hanselman 逐步关闭所有这些验证的技术。你迟早会陷入深渊……
使用 ID 和虚拟字符串(这对 SEO 和人们非常有用)的第二个建议是一种可行的方法,但有时它们也不可行。想象一下这个请求 URL:
/111/Electronics/222/Computers/333/Apple
虽然我们有这些我们可以依赖的 ID 和人类/SEO 友好的类别名称,但这绝对不是我们想要的。当我们需要表示单个项目时,ID + Dummy string 是可行的。在其他情况下不是。而且由于您必须显示类别和子类别,这是一个问题。
那你能做什么?
两种可能的解决方案:
将类别名称清理为仅包含有效字符 - 可以这样做,但如果这些不是静态的并且特权用户无法编辑,那么您在这里就不走运了,因为即使您现在已经清理了它们,稍后有人会输入无效的内容
随时随地清理您的字符串 - 当您使用类别名称时,将其清理并在读取和使用它(以获取实际的类别 ID)时,您可以将提供的(先前清理的)类别名称与您在 DB 中的值进行比较随时清理:
-
现在在过滤类别时
在生成类别名称之前
我建议您采用 2.2 方法。扩展您的数据库表以包含两列:
类别显示名称 类别 URL 友好名称您还可以在第二列上设置唯一约束,这样就不会发生您的两个类别(即使它们具有不同的显示名称)具有相同的 URL 友好名称。
如何清洁
首先想到的是去除无效字符,但这非常繁琐,而且您很可能会遗漏一些内容。从您的类别显示名称中获取有效字符更加容易和明智。我在生成 dummy URL 类别名称时也做了同样的事情。只需取出有效的并将其余的放入垃圾箱。它通常工作得很好。此类正则表达式的两个示例:
(\w2,)
- 只使用字母、数字和下划线,并且至少使用其中两个(因此我们省略了 a 或单个数字和类似的东西,它们不会增加任何意义,并且会不必要地延长我们的 URL
([a-zA-Z0-9]2,)
- 只有字母和数字(也是 2+)
获取您的类别显示名称中的所有匹配项,并用空格/破折号将它们连接起来,并与原始显示名称一起保存。一个不同的question of mine 正是与此有关。
为什么要增加一列?因为您无法在 SQL Server 中运行正则表达式。如果您使用的是 mysql,您可以使用一列并在 DB 上使用正则表达式。
【讨论】:
效果非常好!感谢您的建议,不胜感激:)【参考方案3】:即使您不应该这样做……有时也没有一种简单的方法可以绕过它。 web.Config 中 httpRuntime 标记上的 requestPathInvalidCharacters 是您所寻求的。只需在
<httpRuntime requestPathInvalidCharacters="&lt;,&gt;,*,%,:,\" />
我强烈建议使用以下方法锁定它:
<location path="the/path/you/need/to/lock/down">
<system.web>
<httpRuntime requestPathInvalidCharacters="<,>,*,%,:,\"/>
</system.web>
</location>
只需将其放入根
【讨论】:
以上是关于从客户端检测到潜在危险的 Request.Path 值 (&)的主要内容,如果未能解决你的问题,请参考以下文章
从客户端中检测到有潜在危险的 request.form值[解决方法]