NGINX将%2f转换为正斜杠。我怎么能阻止它?

时间:2011-11-25 02:18:15

标签: url escaping nginx

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

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

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

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

这相当破坏了这个想法。

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

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

然而,(例如)Apache并非如此。

有没有办法解决这个问题?

我已经尝试了文档和谷歌没有运气。

感谢。

更新

nginx config:

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;
        }
    }

}

4 个答案:

答案 0 :(得分:2)

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

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

答案 1 :(得分:1)

有关此问题的更多详细信息,请参见Nginx pass_proxy subdirectory without url decoding,如果您是 proxy_pass 用户,则该解决方案可以提供完整的解决方案。< / p>

使用 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则是http://nginx.org/r/fastcgi_param的规范化(解码和未转义),无查询且可能会被重写的版本(依次,可以通过REQUEST_URI访问)

  fastcgi_param  REQUEST_URI        $request_uri;
  fastcgi_param  DOCUMENT_URI       $document_uri;

但是,在您的情况下,您实际上似乎根本没有指定DOCUMENT_URI,因为如果在当前级别使用http://nginx.org/r/$fastcgi_path_info则不会继承先前的级别,因此很可能解码的路径来自您的http://nginx.org/r/fastcgi_split_path_info,该路径应该与linked answer配对,而您从提供的配置中省略了该路径,因此,原始问题似乎不一致,因为之间的确切路径提供的请求和示例配置也不匹配。

无论如何,fastcgi的最佳解决方案取决于应用程序,并且可能是以下之一:

  • 不依赖于nginx未正确解码和清理的路径。这可能是最好的安全性修复方法,因为您基本上是在要求nginx不要清理/../之类的东西(包括所有转义的变体),这肯定是要保护您免受整个类别的威胁。后端中的漏洞。
  • 重新设计整个界面,以使用QUERY_STRING中的查询参数来确保路径不会被过早混合或解码。
  • 使用REQUEST_URI获取原始请求URI,而无需进行任何规范化或解码。
  • 更加注意使用$uri$document_uri以及可能使用的$fastcgi_path_info的所有实例,这些实例通常包含已解码和标准化的路径。
  • 使用Go Client中概述的重写技巧将未解码的$request_uri放回到$uri中。请注意,如果走这条路线,您可能还必须手动去除查询字符串。

顺便说一句,请注意,您首先要做的是玩弄火,因为如果您不完全了解自己在做什么,并且某天某人确实在做,则很容易引入安全漏洞。决定利用您对这些编码路径的依赖,从而绕过对nginx的正确处理和审查。

您想要做的事情实际上是在Apache上有效,而不是功能上的错误-在设计上,nginx的工作方式与为防止一整类安全漏洞而不同。

答案 2 :(得分:0)

如果您使用网址查询参数,那么您将不会遇到任何问题。 当您可以控制服务器路由时,您可以选择:

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

和nginx不会触及%2f

答案 3 :(得分: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次。