需要在 Apache 上允许编码斜杠

Posted

技术标签:

【中文标题】需要在 Apache 上允许编码斜杠【英文标题】:Need to allow encoded slashes on Apache 【发布时间】:2011-05-22 09:13:51 【问题描述】:

我目前正在尝试在 URL 中放置一个 URL。例如:

http://example.com/url/http%3A%2F%2Fwww.url2.com

我知道我必须对 URL 进行编码,我已经完成了,但现在我从服务器而不是我的应用程序返回一个 404 错误。我认为我的问题在于 apache,可以使用 AllowEncodedSlashes On 指令解决。

我尝试将指令放在 httpd.conf 的底部,但没有效果,我不确定下一步该做什么。我把它放在正确的地方了吗?如果是这样,有人有其他解决方案吗?

【问题讨论】:

除了***.com/a/9933890/6333217:如果你使用RewriteRule而不是ProxyPass你应该添加NE标志以避免解码。 【参考方案1】:

我一直看到这篇文章是为了另一个问题。让我快速解释一下。

我有相同样式的 URL,并且也在尝试代理它。

示例:从/example/ 到另一台服务器的代理请求。

/example/http:%2F%2Fwww.someurl.com/

问题 1: Apache 认为这是一个无效的 url

解决方案:httpd.conf 中的AllowEncodedSlashes On

问题 2: Apache 对编码的斜杠进行解码

解决方案:httpd.conf 中的AllowEncodedSlashes NoDecode(需要 Apache 2.3.12+)

问题 3: mod_proxy 尝试重新编码(双重编码)URL,将%2F 更改为%252F(例如/example/http:%252F%252Fwww.someurl.com/

解决方案:在 httpd.conf 中使用 ProxyPass 关键字 nocanon 将原始 URL 传递给代理。

ProxyPass http://anotherserver:8080/example/ nocanon

httpd.conf 文件:

AllowEncodedSlashes NoDecode

<Location /example/>
  ProxyPass http://anotherserver:8080/example/ nocanon
</Location>

参考:

http://httpd.apache.org/docs/2.2/mod/mod_proxy.html http://www.silverdisc.co.uk/blog/2009/02/28/url-canonicalisation-and-normalisation Cannot match %2F in mod_rewrite

【讨论】:

前两个问题在网络上有很好的记录,但是在我看到这个答案之前,问题 3 是一个难以破解的问题。 谢谢你 这个解决方案就像一个魅力!这应该是答案!谢谢! 哇。完美的答案,作品,简洁。请将此作为接受的答案。 我花了很长时间才找到这个答案。有时一个赞成票根本不够。非常感谢! 我的问题有点不同,但nocanon 解决了它。我在带有 SSL 的 Apache 代理后面安装了 GiLab 综合,并且一些 url(带有斜杠的那些)无法通过。使用canon修复它!很高兴我遇到了这个。【参考方案2】:

此问题与 Apache 错误 35256 无关。而是与错误 46830 有关。AllowEncodedSlashes 设置不被虚拟主机继承,虚拟主机用于许多默认 Apache 配置,例如在Ubuntu。解决方法是在&lt;VirtualHost&gt; 容器中添加AllowEncodedSlashes 设置(在Ubuntu 中为/etc/apache2/sites-available/default)。

Bug 35256:%2F 将在 PATH_INFO 中解码(AllowEncodedSlashes 的文档说不会进行解码)

Bug 46830:如果在全局上下文中设置了AllowEncodedSlashes On,它不会被虚拟主机继承。您必须在每个 &lt;VirtalHost&gt; 容器中显式设置 AllowEncodedSlashes On

关于如何合并不同配置部分的文档说:

&lt;VirtualHost&gt; 部分内的部分应用在虚拟主机定义之外的相应部分之后。这允许虚拟主机覆盖主服务器配置。

【讨论】:

【参考方案3】:

我也在这个问题上浪费了很多时间。我参加聚会有点晚了,但现在似乎有了解决办法。

根据this thread,Apache 中有一个错误,如果您有AllowEncodedSlashes On,它会阻止 404,但它错误地解码斜杠,根据到 RFC。

This comment 提供了一个解决方案,即使用:

AllowEncodedSlashes NoDecode

【讨论】:

【参考方案4】:

考虑到所有的麻烦,我选择了 base64_encoding 和 urlencoding。它可以工作而无需胡乱处理 apache 服务器设置或查看错误报告。它也可以工作,而不必将 url 放在查询部分。

$enc_url = urlencode(base64_encode($uri_string));

然后把它拿回来

$url = base64_decode(urldecode($enc_url));

http://example.com/admin/supplier_show/8/YWRtaW4vc3VwcGxpZXJz

http://example.com/admin/supplier_show/93/YWRtaW4vc3VwcGxpZXJzLzEwMA%3D%3D

【讨论】:

我不喜欢,但最终也这样 你会在这里遇到同样的问题,因为'/'是一个base64字符。 一个 urlencoded / 不管用什么方法制作它仍然是一个%2F 不是吗? php.net 网站上关于 base64_encode() 的顶部评论为 URL 安全版本提供了一个很好的解决方案:php.net/manual/en/function.base64-encode.php#103849 基本上它涉及在编码/解码时用替代字符替换 + 和 /。 【参考方案5】:

在客户端将%2F 替换为%252F

这是正斜杠的双重编码形式。

因此,当它到达服务器并过早解码时,它会将其解码为 %2F,这正是您想要的。

【讨论】:

你永远不应该重复编码:tools.ietf.org/html/rfc3986#section-2.4 @koppor 但是,如果您知道它已被双重编码,则可以对其进行双重解码。所以你可以对整个组件进行双重编码,然后在另一端对那个组件进行第二次解码?【参考方案6】:

经过大量测试并查看 Apache 中的错误后,我得出的结论是,尽管在不同的论坛中提供了解决方案,但这在 Apache 中是一个未解决的问题。查看错误:https://issues.apache.org/bugzilla/show_bug.cgi?id=35256

对我有用的解决方法是重构 URI,以便可以包含转义斜杠的项目位于 URI 的查询部分,而不是路径。我的测试表明,当它们存在时,无论 AllowEncodedSlashes 和 AcceptPathInfo 设置如何,它们都不会被 Apache 过滤掉。

所以:http://test.com/url?http%3A%2F%2Fwww.url2.com

或:http://test.com/url?theURL=http%3A%2F%2Fwww.url2.com

而不是:http://test.com/url/http%3A%2F%2Fwww.url2.com

这意味着我们项目的架构发生了变化,但这似乎是不可避免的。希望您找到了解决方案。

【讨论】:

嗨,罗伯。是的,我得到了相同的结果,所以也必须实施架构更改。有点令人失望,但很高兴它在这个阶段有效。谢谢。【参考方案7】:

我在使用“AllowEncodedSlashes On”时遇到了同样的问题,并尝试将指令放在几个不同的位置:apache2.conf、httpd.conf 和一个部分内,如 http://www.jampmark.com/web-scripting/5-solutions-to-url-encoded-slashes-problem-in-apache.html 的示例。

如果您还没有,您可能希望将日志记录级别设置为调试(另一个指令)并查看是否收到错误:

在 URI (decoded='/url/http://www.url2.com') 中找到 %2f (encoded '/'),​​返回 404

其他未找到的错误不在日志中提供此信息。只是另一个诊断...

祝你好运(我们俩)!

【讨论】:

以上是关于需要在 Apache 上允许编码斜杠的主要内容,如果未能解决你的问题,请参考以下文章

apache ant怎么把路径的斜杠换成正的

如何防止 apache 在 URL 路径中使用单斜杠减少双斜杠?

base64EncodedString 返回不需要的反斜杠

为啥在 URL 的末尾需要一个斜杠?

如何禁用 301 重定向,在 Apache 中将斜杠添加到目录名称

斜杠 ("/") 是不是等同于 HTTP URL 路径部分中的编码斜杠 ("%2F")