假设我想在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;
}
}
}
答案 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
的最佳解决方案取决于应用程序,并且可能是以下之一:
/../
之类的东西(包括所有转义的变体),这肯定是要保护您免受整个类别的威胁。后端中的漏洞。QUERY_STRING
中的查询参数来确保路径不会被过早混合或解码。REQUEST_URI
获取原始请求URI,而无需进行任何规范化或解码。$uri
或$document_uri
以及可能使用的$fastcgi_path_info
的所有实例,这些实例通常包含已解码和标准化的路径。$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次。