mar*_*zzz 5 asp.net-mvc exception .net-4.6.1
我在 ASP.NET MVC Framework 应用程序的处理程序中收到了一些“一般”错误protected void Application_Error()。异常消息是:
\n\n从客户端检测到潜在危险的 Request.Form 值
\n
有很多方法可以触发此操作;仅一个例子是拨打电话,例如
\nhttp:/www.mywebsite.com/http:/www.mywebsite.com/\nRun Code Online (Sandbox Code Playgroud)\n我想仅为这种异常创建一个“过滤器”,并相应地重定向或管理请求。我不想禁用它,只是想管理它。我也不希望它落入通用protected void Application_Error()处理程序\xe2\x80\x94 中,或者至少,我想在该方法内部管理它,这样它就不会被我的日志记录等处理。
我该如何处理这个问题?
\n听起来您已经Application_Error()配置了一个事件处理程序,但不希望您的标准日志记录包含此类错误,大概是因为它使您的日志变得混乱,其中包含您不打算调查的异常更远。
该错误应该由HttpRequestValidationException. 如果这里是这种情况,当然,这将是一个微不足道的问题。然而,根据您提供的测试用例,您实际上得到了更一般的HttpException.
正如您在评论中指出的,这是由于 .NET Framework在请求管道的早期RequestValidator(即评估之前)执行了 URL 中的字符验证。这可能是为什么HttpRequestValidationException不会被抛出的一个因素,否则如果该方法返回,就会发生RequestValidator这种IsValidRequestString()情况false。
不幸的是,由于该类HttpException用于处理各种各样的错误,因此很难处理。幸运的是,正如您还发现的那样RequestValidator,您可以通过禁用requestPathInvalidCharacters并web.config配置自定义来将此验证推送到RequestValidator:
<configuration>\n <system.web>\n <compilation targetFramework="4.6.1" />\n <httpRuntime \n targetFramework="4.6.1" \n requestValidationType="CustomRequestValidator" \n requestPathInvalidCharacters="" \n />\n </system.web>\n</configuration>\nRun Code Online (Sandbox Code Playgroud)\n\n\n注意:假设它
\nrequestValidationType不在项目的根命名空间中,则需要以其命名空间为前缀。
requestPathInvalidCharacters的默认值为<,>,*,%,&,:,\\,?,因此您现在需要在您的 中重现该验证CustomRequestValidator:
public class CustomRequestValidator : RequestValidator\n{\n private static readonly char[] requestPathInvalidCharacters = new [] { \'<\', \'>\', \'*\', \'%\', \'&\', \':\', \'\\\\\' };\n protected override bool IsValidRequestString(\n HttpContext context, \n string value, \n RequestValidationSource requestValidationSource, \n string collectionKey, \n out int validationFailureIndex\n ) {\n if (requestValidationSource is RequestValidationSource.PathInfo || requestValidationSource is RequestValidationSource.Path) {\n var errorIndex = value.IndexOfAny(requestPathInvalidCharacters);\n if (errorIndex >= 0) {\n validationFailureIndex = errorIndex;\n return false;\n }\n }\n return base.IsValidRequestString(\n context, \n value, \n requestValidationSource, \n collectionKey, \n out validationFailureIndex\n );\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n这首先重新创建路径的验证(由参数表示),然后从基础value执行标准的开箱即用处理。现在这将抛出预期的.IsValidRequestString()RequestValidatorHttpRequestValidationException
此时,如上所述,这已成为一个微不足道的问题。由于RequestValidator在解析 MVC 路由之前对其进行评估,因此您仍然无法在此处使用全局异常过滤器。但是,由于您已经有了一个Application_Error()事件处理程序设置,因此您可以global.asax.cs使用以下命令来管理它:
void Application_Error(object sender, EventArgs e)\n{\n\n Exception ex = Server.GetLastError();\n\n if (ex is HttpRequestValidationException)\n {\n Response.Clear();\n Response.StatusCode = 200;\n // Manage request as you deem appropriate; e.g.,\n Response.Redirect("~/Errors/RequestValidation/");\n Response.End();\n return;\n }\n\n // Your current logging logic\n\n}\nRun Code Online (Sandbox Code Playgroud)\n几乎每个 ASP.NET 请求\xe2\x80\x94都会至少RequestValidator调用两次 ,一次针对( 通常为空) ,一次针对(请参阅)。绑定到路由的每个、、、或 文件也将被验证。pathinfopathrequestValidationSourceQueryStringFormCookieHeader
Microsoft 试图限制需要验证的请求。例如,他们不检查对静态文件的请求。此外,未绑定到路由的参数将被跳过。由于潜在危险的字符不能在路由参数键中使用,因此我们不需要担心验证这些字符。
\n此外,正如您所指出的,也不需要验证无效路径字符的参数值(例如 cookie 值)。集合值仍将由基本逻辑评估是否存在其他潜在危险字符串\xe2\x80\x94,例如\xe2\x80\x94 。<scriptIsValidRequestString()
| 归档时间: |
|
| 查看次数: |
13564 次 |
| 最近记录: |