作为互联网上最常用的Web服务器之一,Nginx因轻巧、模块化并且有对用户友好的配置格式而广受欢迎。一旦Nginx出现错误配置,那么你的网站就很危险。Detectify分析了从GitHub下载的近50000个不重复的Nginx配置文件,发现了一些常见的错误配置:
根目录位置丢失
server {
root /etc/nginx;
location /hello.txt {
try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1:8080/;
}
}
root指令指定Nginx的根文件夹。在上面的示例中,根文件夹是,这意味着我们可以访问该文件夹中的文件。上面的配置没有针对的位置,只有的位置。因此,root指令会被设置为全局,这意味着对的请求会将你带到本地路径。
像这样简单的请求都能显示存储在/中Nginx配置文件的内容。如果将根设置为,则对的请求将显示配置文件。在某些情况下,访问者可能会访问其他配置文件、访问日志甚至HTTP基本身份验证的加密凭据。
在我们收集的近50000个Nginx配置文件中,最常见的根路径如下:
经常配置错误的Nginx根路径
off-by-slash
server {
listen 80 default_server;
server_name _;
location /static {
alias /usr/share/nginx/static/;
}
location /api {
proxy_pass http://apiserver/v1/;
}
}
这个配置错误指的是由于缺少一个斜杠,所以有可能沿路径上移一步。OrangeTsai在Blackhat演讲 中让这项技术广为人知。
在这个演讲中,他展示了如何结合一条缺少尾斜杠的指令与一条指令,来读取Web应用程序的源代码。鲜为人知的是,它还可以与其他指令(例如)一起使用。我们来分解一下究竟发生了什么事情,以及为什么它能起作用。
location /api {
proxy_pass http://apiserver/v1/;
}
如果一个Nginx服务器运行能在server访问的以下配置,则可以假定访问者只能访问下的路径。
http://server/api/user -> http://apiserver/v1//user
当请求时,Nginx将首先规范化URL。然后,它会查看前缀/是否与URL匹配,本例中是匹配的。
然后,服务器从URL中删除该前缀,保留路径。再将此路径添加到 URL中,从而得到最终URL 。
请注意,这个URL中存在双斜杠,因为location指令不以单斜杠结尾,并且 URL路径以单斜杠结尾。大多数Web服务器会将标准化为,这意味着即使配置错误,所有内容仍将按预期运行,并且可能不会引起注意。请求可以利用这种错误配置,这将导致Nginx请求URL ,其标准化为。这可能产生的影响取决于利用这种错误配置可以达到的效果。例如,这可能导致Apache服务器状态通过URL 公开,或者可能让不希望公开访问的路径可访问。
Nginx服务器配置错误的一个迹象是,当URL中的一个斜杠被删除时,服务器仍会返回相同的响应。例如,如果和返回相同的响应,则服务器可能容易受到攻击。这将导致发送以下请求:
http://server/api/user -> http://apiserver/v1//user
http://server/apiuser -> http://apiserver/v1/user
不安全的变量使用
一些框架、脚本和Nginx配置会不安全地使用Nginx存储的变量。这可能会导致诸如XSS、绕过HttpOnly保护、信息泄露,甚至在某些情况下的RCE之类的问题。
SCRIPT_NAME
像下面这样的配置:
location ~ \.php$ {
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
}
主要问题是Nginx会将所有URL发送到以结尾的PHP解释器,即使该文件在磁盘上不存在。这是Nginx创建的“”文档中提到的,在许多Nginx配置中都常见的错误。如果这个PHP脚本试图基于定义一个基本URL,则将发生XSS。
if(basename($_SERVER['SCRIPT_NAME']) ==
basename($_SERVER['SCRIPT_FILENAME']))
echo dirname($_SERVER['SCRIPT_NAME']);
?>
GET /index.php//index.php
SCRIPT_NAME = /index.php//index.php
使用$uri可导致CRLF注入
与Nginx变量有关的另一个错误配置是使用或代替。和包含标准化的URI,而Nginx中的包括对URI解码的URL。Volema发现,在Nginx配置中创建重定向时经常会使用,结果导致CRLF注入。
一个易受攻击的Nginx配置的示例如下:
location / {
return 302 https://example.com$uri;
}
HTTP请求的换行符为\r(回车)和\n(换行)。对换行符进行URL编码将导致以下字符表示形式。如果将这些字符包含在对配置错误的服务器的一个请求中(例如),则该服务器将使用一个名为的新标头进行响应,因为$uri变量包含URL解码的换行符。
HTTP/1.1 302 Moved Temporarily
Server: nginx/1.19.3
Content-Type: text/html
Content-Length: 145
Connection: keep-alive
Location: https://example.com/
Detectify: clrf
Any变量
在某些情况下,用户提供的数据可以视为Nginx变量。目前尚不清楚为什么会发生这种情况,但如这份所示,这种情况并不罕见或不容易测试。如果搜索错误消息,我们可以看到它是在中找到的,表明这是由SSI引起的。
一种测试方法是设置一个引用标头值:
$ curl -H ‘Referer: bar’ http://localhost/foo$http_referer | grep ‘foobar’
我们扫描了这种错误配置,发现了几个实例,用户可以在其中打印Nginx变量的值。我们发现易受攻击实例的数量有所下降,这可能表明这个漏洞已经做了修补。
原始后端响应读取
使用Nginx的,可以拦截后端创建的错误和HTTP标头。如果你要隐藏内部错误消息和标头以便Nginx处理,这个方法会非常有用。如果后端回答一个错误,Nginx将自动提供一个自定义错误页面。但如果Nginx无法理解这是一个HTTP响应怎么办?
如果一个客户端向Nginx发送了一个无效的HTTP请求,则该请求将按原样转发到后端,后端将使用其原始内容来应答。然后,Nginx将无法理解无效的HTTP响应,而将其转发给客户端。想象一个这样的uWSGI应用程序:
def application(environ, start_response):
start_response('500 Error', [('Content-Type',
'text/html'),('Secret-Header','secret-info')])
return [b"Secret info, should not be visible!"]
并在Nginx中使用以下指令:
http {
error_page 500 /html/error.html;
proxy_intercept_errors on;
proxy_hide_header Secret-Header;
}
如果后端的响应状态大于300,将提供一个自定义响应。在上面的uWSGI应用程序中,我们将发送一个,Nginx将拦截该错误。
可以自解释;它将从客户端隐藏任何指定的HTTP标头。
如果我们发送一个普通的GET请求,则Nginx将返回:
HTTP/1.1 500 Internal Server Error
Server: nginx/1.10.3
Content-Type: text/html
Content-Length: 34
Connection: close
但是,如果我们发送一个无效的HTTP请求,例如:
GET /? XTTP/1.1
Host: 127.0.0.1
Connection: close
我们将收到以下答复:
XTTP/1.1 500 Error
Content-Type: text/html
Secret-Header: secret-info
Secret info, should not be visible!
merge_slashes设置为off
默认情况下,指令设置为“on”,这是一种将两个或多个正斜杠压缩为一个的机制,因此将变为。如果Nginx用作反向代理,并且被代理的应用程序容易受到本地文件包含内容的影响,则在请求中使用额外的斜杠可能会留出恶意利用空间。
我们发现33个Nginx配置文件的设置为“off”。
自己尝试一下
我们创建了一个,你可以在其中使用Docker来设置你自己的易受攻击的Nginx测试服务器,以及本文中讨论的一些错误配置,然后尝试自己找到它们。
总结
Nginx是一个非常强大的Web服务器平台,很好理解为什么它会被广泛使用。但是,灵活的配置意味着你更容易犯错误,而这些错误可能会对安全性产生影响。请不要使用这些常见的错误配置,以免攻击者轻易地入侵你的网站。
原文链接:
https://blog.detectify.com/2020/11/10/common-nginx-misconfigurations/?fileGuid=xVX6hcx8WXCYPVGd