我有一个在 IIS 7.0 上运行的标准 ASP.Net WebForms 应用程序,带有集成托管管道。我们网站上的许多图像的文件名中都有空格(例如'./baseball drawing.gif'
)。当我们将这些图像放入 html 页面时,我们对路径进行 url 编码,以便我们的 html img 标签看起来像这样 img src='./baseball%20drawing.gif' />
现在,当某些搜索引擎和网络爬虫尝试对我们的网站建立索引时,问题就出现了。当他们抓取我们的页面时,他们会对我们已经 html 编码的路径进行 html 编码,获取像这样的图像链接'./baseball%2520drawing.gif'
where %25
是 '%' 的 url 编码。这会导致两个问题:
- 当用户从这些搜索引擎获取结果时,他们会收到损坏的链接。
- 当用户尝试导航到这些损坏的链接时,它会在我们的系统中引发错误。
正如你所看到的,这是一个双输的局面。用户会收到损坏的链接,并且我们会在错误日志中收到噪音。
我一直在试图找出如何解决这个问题但没有运气。这是我尝试过的:
- Set
<requestFiltering allowDoubleEscaping='true'>
在 web.config 中防止“404.11 URL 双重转义错误”。这修复了第一个错误,但导致了一个新错误,“发现了潜在危险的 Request.Path”。
- 删除了“%”
<httpRuntime requestPathInvalidChars>
以防止“潜在危险的Request.Path”错误。这修复了第二个错误,但现在我们有了第三个错误,“找不到资源”。
- 我在代码中放置了一个中断来观看
Request.Path
。看起来值“Ball Image.gif”而不是“Ball%2520Image.gif”是正确的。在这种情况下,我不确定为什么它不起作用。
我觉得我有一个超级黑客,我必须禁用所有功能,而没有真正理解为什么没有任何效果。所以我想我的问题有三个方面
- 为什么解决方案尝试 1 无法解决问题?
- 为什么解决方案2没有解决问题?
- 为什么我的 Request.Path 在步骤 3 中看起来正确,但仍然不起作用?
任何人可以提供的任何帮助将不胜感激。
好吧,经过大量的互联网搜索和大量的实验后,我想我终于明白发生了什么。我的主要问题是极端的确认偏差。我读到的所有内容都是我想听的,而不是实际所说的。为了回答我的问题,我将大大总结我需要理解的要点。
首先,我需要了解 IIS 和 ASP.Net 是两个不同的应用程序。简而言之,IIS 的作用是接收请求,将该请求路由到处理该请求的应用程序,从处理应用程序获取输出,然后将应用程序的输出发送回请求者。 ASP.Net 的作用是接收来自 IIS 的请求,处理它,然后将响应传递回 IIS。这是对整个过程的过度概括,但就我的目的而言,这已经足够好了。1 http://learn.iis.net/page.aspx/243/aspnet-integration-with-iis/
传入的 ASP.Net 请求必须通过两个网守。 IIS7 RequestFiltering模块(在system.webserver/requestFiltering中配置2 http://www.iis.net/ConfigReference/system.webServer/security/requestFiltering),然后是 ASP.Net HttpRuntime 请求过滤器(在 system.web/httpRuntime 中配置3 http://msdn.microsoft.com/en-us/library/e1f13641.aspx).
IIS RequestFiltering 模块是唯一对传入请求进行规范化的模块,并且它仅应用规范化一次。我再次重复一遍,它只应用一次。即使<requestFiltering allowDoubleEscaping="true" />
它仍然只会应用一次标准化。这意味着“%2520”将被标准化为“%20”。此时,如果 allowedDoubleEscaping 为 false,IIS 将不会让请求通过,因为“%20”仍可以正常化。但是,如果将allowDoubleEscaping 设置为true,则IIS7 会将请求“%20”传递给下一个网守ASP.Net。这是第一个错误的原因。
Asp.net 过滤器是检查 requestPathInvalidCharacters 的地方。所以现在我们的 '%20' 无效,因为默认情况下 '%' 是 requestPathInvalidCharacters 的一部分。如果我们从该列表中删除“%”,我们将使其通过第二个网守,并且 ASP.Net 将尝试处理我们的请求。这就是第二个错误的原因。
现在 ASP.net 将尝试将我们的虚拟路径转换为服务器上的物理路径。不幸的是,我们的路径中仍然有一个“%20”,而不是我们想要的“ ”,因此 ASP.Net 无法找到我们想要的资源,并抛出“找不到资源错误”。当我闯入代码时,该路径看起来正确的原因是我在 Request.Url 属性上放置了一个监视。该属性试图通过在其 ToString() 方法中应用其自己的规范化来提供帮助,从而使我们的 %20 看起来像我们想要的 ' ',尽管事实并非如此。这就是导致最终错误的原因。
为了完成这项工作,我们可以编写自己的自定义模块,该模块在前两个网守之后接收请求,并在将其传递给 ASP.Net 之前对其进行完全规范化。不过,这样做将允许任何字符通过,只要它是 URL 编码的。例如,我们通常不想在路径中允许使用“”,因为它们可用于将标签插入到我们的代码中。目前, 不会通过 ASP.Net 过滤器,因为它们是 requestPathInvalidCharacters 的一部分。但是,如果我们打开前两个门,然后在我们自己的自定义模块中规范化请求,然后再将其传递给 ASP.Net,则可以将其编码为 %253C 和 %253E。
总之,如果不造成大的安全漏洞,就不可能允许 %2520 完全标准化。如果可以告诉 RequestFiltering 模块在针对前两个网守测试该请求之前完全规范化它收到的每个请求,那么它会更安全,但现在该功能不可用。
如果我有任何问题,请告诉我,我希望这对某人有帮助。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)