为什么在 URI 中允许编码斜杠会带来安全风险?

发布于 2024-11-05 17:28:10 字数 804 浏览 0 评论 0原文

我遇到了一种情况,我希望在 URI (%2F) 中编码斜杠,但当我发出请求时,我的 .htaccess 规则将被忽略,而是将我发送到 404页。我很快找到了 Apache 指令 AllowEncodedSlashes,我打算打开它,但我仍然不明白为什么它首先会带来安全风险。如果有人试图作恶,就不能手动将编码的斜杠转换为真正的斜杠吗? (虽然我看不出它们会造成什么危害...)

我正在测试的应用程序是用 PHP 编写的,与其交互的 mod_rewrite 规则如下所示:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^test/(.*)$ /test.php?_escaped_fragment_=$1 [NE,QSA,L]

我只是想确保在继续之前了解风险。


澄清一下:Apache 不允许在路径中使用编码斜杠,但在查询字符串中允许使用编码斜杠。查询字符串同样容易受到 Christian 下面列出的漏洞的影响(“远程代码执行、本地文件访问和目录遍历”)。

那么,为什么 ASF 甚至要创建一个特殊指令来允许这种行为呢?我并不是想难为难,我只是真的不明白。我认为不言而喻,任何用户输入(包括 URI)在用于任何数据库或文件系统功能之前都需要进行验证。

I have a situation where I want encoded slashes in a URI (%2F), but my .htaccess rules are ignored when I make the request, sending me instead to a 404 page. I quickly found the Apache directive AllowEncodedSlashes, which I plan to turn on, but I still don't understand why it's a security risk in the first place. Couldn't anyone manually transform the encoded slashes to real slashes, if they were trying to be nefarious? (Although I can't see what harm they could do...)

The application I'm testing is written in PHP, and the mod_rewrite rule that interfaces with it looks like:

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^test/(.*)$ /test.php?_escaped_fragment_=$1 [NE,QSA,L]

I just want to make sure I understand the risks before proceeding.


To clarify: Apache does not allow encoded slashes in the path, but they are allowed in the query string. The query string is just as susceptible to the exploits listed by Christian below ("Remote Code Execution, Local File Access and Directory Traversal").

So why did the ASF go so far as to create a special directive just to allow this behavior? I'm not trying to be difficult, I just really don't understand. I think it goes without saying that any user input (including the URI) needs to be verified before using it in any database or file system function.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

独守阴晴ぅ圆缺 2024-11-12 17:28:10

我认为如果转义是必要的,那么在 URL 中的任何地方使用转义斜杠都是可以的。例如,以下(相关)问题中引用的示例是一个非常合理的示例:

lash-2f-in-the-path-portion-of-an">斜杠(“/”)是否等同 为什么它默认情况下将被禁用...这篇 2003 年的博客文章表明它是为了“保护蹩脚的 CGI 脚本免受自身侵害”:

http://ken.coar.org/burrow/Apache_2f_encoding_decoding_and_security

某些粗心的做法可能会导致某些人发现自己陷入困境带有字符串的代码库,他们不确定是否要转义。所以他们“为了安全”而逃避它。但这可能发生在假设没有路径字符的点之后......并且它被传递到一些可执行上下文中,该上下文相信它已经完成了所需的所有检查。

因此,如果您使用大多数现代 Web 框架的推荐方法,我怀疑这是一个重大问题,您可以不用太担心地使用AllowEncodedSlashes。

I would think it is fine to use escaped slashes anywhere in a URL if escaping is warranted. For instance, the example cited in the following (relevant) question is a very reasonable one:

Is a slash ("/") equivalent to an encoded slash ("%2F") in the path portion of an HTTP URL

As for why it would be disabled by default...this blog entry from back in 2003 suggests it is to "protect lame CGI scripts from themselves":

http://ken.coar.org/burrow/Apache_2f_encoding_decoding_and_security

Certain careless practices probably lead some people to find themselves in a codebase with a string they're unsure whether to unescape or not. So they unescape it "just to be safe". But this may occur after a point that assumed there were no path characters... and it gets passed on into some executable context that believed it had done all the checking it needed to.

So if you're using the recommended methods of most modern web frameworks, I doubt this is a significant issue and you can use AllowEncodedSlashes without much concern.

阳光①夏 2024-11-12 17:28:10

老实说,我没有看到任何安全问题,但我必须承认我在这个领域工作得不多。也就是说,该规则仍然不正确。

您应该重定向到解析 $_SERVER['REQUEST_URI'] 的处理程序文件(php 脚本),而不是通过 $_GET 传递它。这主要是为了避免非编码内容通常会出现的问题。

另一方面,您可能正在运行 Web 应用程序防火墙,其中包含禁止通过 URI 传递斜杠的规则。这是因为此行为通常与远程代码执行本地文件访问目录遍历相关。
然而,这是一种预防措施,您一开始就不应该依赖它。

PoC 漏洞利用示例:

include 'languages/'.$_GET['lang']; // hacker may pass ../ to move around.

Honestly, I don't see any security issues with this, but I must admit I've not worked in this field much. That said, the rule is still not correct.

You should be redirecting to a handler file (php script) which parses $_SERVER['REQUEST_URI'] instead of passing it through $_GET. This is mostly to avoid issues you'd normally get with non-encoded content.

On the other hand, you may be running a web app firewall with a rule against passing slashes through URI. This is because this behavior is often associated with Remote Code Execution, Local File Access and Directory Traversal.
This, however, is a precautionary measure, one which you really shouldn't rely on in the first place.

An example PoC exploit:

include 'languages/'.$_GET['lang']; // hacker may pass ../ to move around.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文