正确处理 URL 中带有百分号 (/%) 的 IIS 请求

正确处理 URL 中带有百分号 (/%) 的 IIS 请求

我正在寻找任何一种解决方案来正确获取 IIS 请求,例如https://stackoverflow.com/%http://bing.com/%不显示 400 错误请求页面,而是显示类似于http://google.com/%http://facebook.com/%做(显然这些例子不在 IIS 上)。

我相信我已经尝试设置所有适用的 http.sys 注册表设置(AllowRestrictedChars、PercentUAllowed)http://support.microsoft.com/kb/820129但这并没有帮助。设置 AllowRestrictedChars 和自定义 400 页面有固定的 URL,例如https://stackoverflow.com/但不是 /%。

答案1

这在 IIS 内核级别被阻止。为了进行测试,我拔出了每一个IIS 中的模块,因此它甚至没有静态页面处理程序,但仍然显示 400 错误消息。

我认为使用 IIS 无法解决这个问题。您提到的注册表设置适用于其他类型的受限字符。我还没有看到可以更改该功能的杠杆。

你避免这种情况的目的是什么?这会扩大你的攻击面,我无法想象由于阻止不完整的 URL 转义序列而导致合法访问者流失。

更新2: 以下是关于此问题的三个很棒的链接。IIS 团队的 Nazim Lala 和 Wade Hilmo 都曾就此问题发表过博文,因为有人就您的问题展开了讨论。此外,Scott Hanselman 还发表了一篇关于 .NET 中的查询字符串部分的精彩博文:

更新: 我咨询了 IIS 团队的一名成员,得到了权威的答案。他提到,根据 RFC 1738,% 被视为不安全字符 (http://www.ietf.org/rfc/rfc1738.txt)。

以下是相关文字:

不安全:

字符不安全的原因有很多。空格字符不安全,因为在转录或排版 URL 或对其进行文字处理程序处理时,重要的空格可能会消失,而无关紧要的空格可能会被引入。字符“<”和“>”不安全,因为它们在自由文本中用作 URL 周围的分隔符;在某些系统中,引号(“””)用于分隔 URL。字符“#”不安全,应始终进行编码,因为它在万维网和其他系统中用于分隔 URL 和可能跟在其后的片段/锚点标识符。 字符“%”不安全,因为它用于其他字符的编码。 其他字符是不安全的,因为网关和其他传输代理有时会修改这些字符。这些字符包括“{”、“}”、“|”、“\”、“^”、“~”、“[”、“]”和“`”。

所有不安全字符都必须在 URL 中编码。例如,即使在通常不处理片段或锚点标识符的系统中,也必须在 URL 中对字符“#”进行编码,这样如果将 URL 复制到使用它们的另一个系统中,就无需更改 URL 编码。

因此,IIS 会在核心层面主动阻止这种行为,这是一种主动的安全措施,可以最大限度地减少其攻击面。

答案2

解决这个问题的唯一方法似乎是在 IIS 内核之前检查 URL。

您需要通过脚本发送动态生成的链接,以便在将最终用户转发到该 URL 之前对其进行检查...

除此之外,您知道这是 IIS 不会按您希望的方式处理的唯一情况。因此,通过排除法,如果您有未处理的请求,您就知道是什么原因造成的。

也许检查自定义 400 页面中的引荐来源有助于缩小流量来源?

答案3

我能想到三种可能的方法

  1. 将 IIS 更改为指向自定义页面,以解决 400 错误

  2. 如果这对于 IIS 中的特定网站来说是唯一的,您可以在 web.config 中执行如下操作:

    <customErrors defaultRedirect="ErrorPage.aspx" mode="On">
    <error statusCode="400" redirect="myCustom400Error.aspx" />
    </customErrors>

  3. 编写一个 httpModule 来检查传入的 URL 并处理它们

答案4

邮政在 IIS 论坛上表明 HTTP 400(错误请求)被 http.sys 阻止并且无法到达 IIS,这与@Scott Forsyth - MVP 在其原始答案中包含的链接相匹配。

您可以在 c:\Windows\System32\LogFiles\HTTPERR\ 下查看这些请求的日志

我不知道您是否可以配置针对此类错误发送回用户的响应页面,但由于 Bing 也受到此问题的影响,我怀疑这是不可能的,或者需要一些可怕的系统黑客。

相关内容