从客户端检测到潜在危险的Request.Path值(?)

时间:2017-05-09 04:05:52

标签: c# asp.net iis

环境

IIS 8.5

.NET Framework版本:4.6.2(使用WebForms)

Windows Server 2012 R2

问题:

报告了以下异常:

BASE EXCEPTION: System.Web.HttpException (0x80004005): A potentially dangerous Request.Path value was detected from the client (?).
   at System.Web.HttpRequest.ValidateInputIfRequiredByConfig()
   at System.Web.HttpApplication.PipelineStepManager.ValidateHelper(HttpContext context)

BASE EXCEPTION HRESUT: -2147467259

EXCEPTION: System.Web.HttpException (0x80004005): A potentially dangerous Request.Path value was detected from the client (?).
   at System.Web.HttpRequest.ValidateInputIfRequiredByConfig()
   at System.Web.HttpApplication.PipelineStepManager.ValidateHelper(HttpContext context)

我们的日志中显示的其他信息:

PATH_INFO
/cities/index.aspx?locid=4163
----
QUERY_STRING
----
REMOTE_ADDR
66.249.65.204
----
REMOTE_HOST
66.249.65.204
----
REQUEST_METHOD
GET
----
SCRIPT_NAME
/cities/index.aspx?locid=4163
----
URL
/cities/index.aspx?locid=4163
----
HTTP_FROM
googlebot(at)googlebot.com
----
HTTP_USER_AGENT
Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)

我不明白的是,如果我在浏览器中剪切并粘贴路径,页面就会正常呈现并且没有错误。

问题:

  1. 为什么googlebot在抓取页面时会产生此错误,但是当我在浏览器中输入路径时没有生成错误? (我觉得奇怪的是错误日志没有显示查询字符串的值,即使它存在)。
  2. 为什么是“?”被认为有潜在危险的角色?
  3. 任何建议都会受到赞赏,因为我试图了解当路径实际上有效时如何引发这个特殊的“错误”。

    提前致谢。

3 个答案:

答案 0 :(得分:2)

从Asp.net 4.0+引入了严格的验证,因此您所看到的错误可能是其中的一部分。 url中存在某些可能导致XSS攻击的dangerouss字符。所以?就是其中之一。其余字符如下:

< > * % & : \ ?

可能有两种解决方案

  1. 您可以通过在web config中配置以下配置,在您的网址或至少某个字符中允许这些字符,如下所示

    <system.web> <httpRuntime requestPathInvalidCharacters="&lt;,&gt;,*,%,&amp;,:,\,?" /> </system.web>

  2. 您可以使用以下配置回滚到asp.net 2.0

    <system.web> <httpRuntime requestValidationMode="2.0" /> </system.web>

答案 1 :(得分:0)

我突然意识到为什么查询字符串在我们的日志中没有显示任何内容。  编码“?”的请求(%3f)将导致引发上述异常,例如:

/cities/index.aspx%3flocid=4163

编码的%3f被解释为路径的一部分,因此从客户端(?)检测到“有潜在危险的Request.Path值”的例外。

当我在浏览器中输入上面显示的URL时 - 引发异常并且日志不包含查询字符串。所以我只能假设一切正常,请求者正在编码?什么时候不应该;基本上破坏了URL的查询字符串部分。

我们在system.web中也有requestValidationMode =“2.0”,但是不要使用requestPathInvalidCharacters(httpRuntime)设置。

答案 2 :(得分:0)

如果您(或一个测试者)访问网址https://domain.tld/<foobarhttps://domain.tld/</,也会发生同样的情况。

即使启用了自定义错误页面,这也会返回由IIS呈现的错误页面,如果您在Application_Error中记录错误,您可能会发现您的日志中充满了来自扫描程序/机器人/等的噪音。

我发现一个相当简单的解决方法是在Global.asax.cs中处理Application_Error中的HttpException异常。这样您就不需要使用requestValidationMode进行调整。

  1. 在应用程序的根目录中创建以下页面:

    • 400.html - 适用于IIS
    • 400.aspx - for ASP.NET
    • 404.html - for IIS
    • 404.aspx - for ASP.NET
    • 500.html - 适用于IIS
    • 500.aspx - 用于ASP.NET
        

      .html文件包含以下内容:

           
      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="utf-8" />
          <title>400 Bad request</title>
      </head>
      <body>
          <h1>400 Bad request</h1>
      </body>
      </html>
      
        
           

      .aspx文件包含以下内容:

           
      <%@ Page Language="C#" %>
      <%
          Response.StatusCode = 400;
          Server.Transfer("~/400.html");
      %>
      
        
           

      确保在.aspx文件中设置相应的响应状态代码。

  2. 配置ASP.NET的自定义错误,如下所示:

    <customErrors mode="RemoteOnly" redirectMode="ResponseRewrite" defaultRedirect="~/500.aspx">
      <error statusCode="400" redirect="~/400.aspx"/>
      <error statusCode="404" redirect="~/404.aspx"/>
      <error statusCode="500" redirect="~/500.aspx"/>
    </customErrors>
    
  3. 配置IIS的自定义错误,如下所示:

    <httpErrors errorMode="DetailedLocalOnly">
     <remove statusCode="400"/>
     <error statusCode="400" path="400.html" responseMode="File"/>
     <remove statusCode="404"/>
     <error statusCode="404" path="404.html" responseMode="File"/>
     <remove statusCode="500"/>
     <error statusCode="500" path="500.html" responseMode="File"/>
    </httpErrors>
    
  4. 相应地调整Global.asax.cs:

    protected void Application_Error(object sender, EventArgs e)
    {
        var lastError = Server.GetLastError();
        Server.ClearError();
    
        if (lastError.GetType() == typeof(HttpException))
        {
            Response.StatusCode = 400;
            Server.Transfer("400.html");
        }
        else
        {
            Response.StatusCode = 500;
            Server.Transfer("500.html");
    
            // logging
        }
    }
    
  5. 有关如何设置自定义错误页面的完整故事,请参阅http://benfoster.io/blog/aspnet-mvc-custom-error-pages,有关错误处理程序的更多信息,请参阅https://msdn.microsoft.com/en-us/library/bb397417.aspx