NGINX 将 %2f 转义为正斜杠。我怎样才能阻止它?

问题描述 投票:0回答:5

假设我想在 URL 中对包含斜杠的文章标题进行编码。如果我对文章标题进行 URL 编码,我会得到:

http://example.com/articles/foo%2fbar/view/

NGINX 将其传递给我的 FastCGI 应用程序:

http://example.com/articles/foo/bar/view/

这反而毁了这个想法。

我注意到,如果 NGINX 正在提供一个文件,例如 /path/to/page.html,那么可以通过以下两个 URL 之一访问它:

http://example.com/path/to/page.html
http://example.com/path/to%2fpage.html

但是(例如)Apache 的情况并非如此。

有什么办法可以解决这个问题吗?

我尝试过文档和谷歌,但没有成功。

谢谢。

更新

nginx 配置:

worker_processes  1;
pid ./nginx.pid;
events {
    worker_connections  1024;
}
http {
    server_tokens off;
    server {
        listen 80;
        server_name localhost;
        location /mysite/{
            fastcgi_pass   unix: ./mysite.fcgi.socket;

            fastcgi_param SERVER_NAME $server_name;
            fastcgi_param SERVER_PORT $server_port;
            fastcgi_param SERVER_PROTOCOL $server_protocol;
            fastcgi_param SCRIPT_NAME "/mysite/";
            fastcgi_param PATH_INFO $fastcgi_path_info;
            fastcgi_param REQUEST_METHOD $request_method;
            fastcgi_param QUERY_STRING $query_string;
            fastcgi_param CONTENT_TYPE $content_type;
            fastcgi_param CONTENT_LENGTH $content_length;
            fastcgi_pass_header Authorization;
            fastcgi_intercept_errors off;
        }
    }

}
url escaping nginx
5个回答
2
投票

尝试将“%”转义为“%25”

http://example.com/articles/foo%252fbar/view/

2
投票

有关此问题的更多详细信息,请参阅 Nginx pass_proxy 子目录,无需 url 解码,如果您是

proxy_pass
用户,这里有完整的解决方案。

使用

fastcgi_pass
,可能会发生这种情况,因为 nginx 中默认的
conf/fastcgi.conf
,其中
DOCUMENT_URI
变量设置为 http://nginx.org/r/$document_uri,其中相当于 http://nginx.org/r/$uri,而它又是 http://nginx.org/ 的标准化(解码和未转义)、无查询且可能重写的版本r/$request_uri (反过来,可以通过
REQUEST_URI
访问):

  fastcgi_param  REQUEST_URI        $request_uri;
  fastcgi_param  DOCUMENT_URI       $document_uri;

但是,在您的情况下,您实际上似乎根本没有指定

DOCUMENT_URI
,因为 http://nginx.org/r/fastcgi_param 如果在当前级别使用,则不会从先前级别继承,因此,解码的路径可能来自您的 http://nginx.org/r/$fastcgi_path_info,它应该与您省略的 http://nginx.org/r/fastcgi_split_path_info 配对从提供的配置来看,因此,原始问题可能看起来不一致,因为提供的请求和示例配置之间的确切路径也不匹配。

无论如何,使用

fastcgi
的最佳修复将取决于应用程序,并且可能是以下其中之一:

  • 不依赖于 nginx 未正确解码和清理的路径。这可能是安全方面最好的修复,因为你基本上要求 nginx 不要清理像
    /../
    这样的东西(包括所有转义的变体),这当然是为了保护你免受一整类漏洞的侵害。你的后端。
  • 重新设计整个界面以使用
    QUERY_STRING
    中的查询参数,以确保路径不会过早混合或解码。
  • 使用
    REQUEST_URI
    获取原始请求 URI,无需进行任何标准化或解码。
  • 密切注意使用
    $uri
    $document_uri
    的所有实例,也可能使用
    $fastcgi_path_info
    ,它们通常包含解码和标准化路径。
  • 使用链接答案中概述的重写技巧将未解码的
    $request_uri
    放回到
    $uri
    中。请注意,如果您选择此路线,您可能还需要手动删除查询字符串。

顺便说一句,请注意,您首先所做的事情有点像玩火,因为如果您不完全了解自己在做什么,并且有一天有人决定这样做,那么很容易引入安全漏洞利用您依赖这些编码路径绕过 nginx 的正确处理和审查。

事实上,你想要做的事情在 Apache 中按原样工作更多的是一个错误而不是一个功能 - 这在 nginx 中的设计不同,目的是防止一整类安全漏洞。


0
投票

我的 nginx + uWSGI + Flask 堆栈也有同样的问题。 我通过在 nginx 配置中引入重写规则解决了这个问题:

location @app {
    rewrite ./ $request_uri break;
    include uwsgi_params;
    uwsgi_pass unix:/tmp/uwsgi.sock;
}

更新:这似乎破坏了查询参数,所以我必须这样做:

location @app {
    set $plain_uri $request_uri ;
    if ( $plain_uri ~ (.*)\?.* ) {
        set $plain_uri $1 ;
    }
    rewrite .* $plain_uri break;
    include uwsgi_params;
    uwsgi_pass unix:/tmp/uwsgi.sock;
}

这样做的问题是,原来编码的 URL 又被编码了,所以我总共需要取消编码 4 次。


0
投票

此答案仅与问题标题相关。

如果你正在做

location / {
  proxy_pass https://example.com/;
}

根据 to this thread,您需要将其更改为不包含尾随斜杠 - 显然,当您不使用尾随斜杠时,它会以不同的方式转发请求。

location / {
  proxy_pass https://example.com;
}

如果您的“位置”不只是针对“/”,而是针对某些子目录,您可能会遇到其他其他问题,这些问题在此处进行了描述和回答


-1
投票

如果使用 URL 查询参数,就不会有任何麻烦。 当您可以控制服务器路由时,您可以选择:

http://example.com/articles/view/?path=foo%2fbar

并且 nginx 不会接触 %2f

© www.soinside.com 2019 - 2024. All rights reserved.