社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  NGINX

五个常见的Nginx配置错误

AI前线 • 4 年前 • 569 次点击  
作者 | Crowdsource
译者 | 王强
策划 | 万佳
Nginx 是最常见的 Web 服务器。本文介绍五个常见的配置错误,它们会降低网站的安全性。

Nginx 错误配置如果不能及时修正,它会让你的网站陷入网络攻击的风险。

作为互联网上最常用的 Web 服务器之一,Nginx 因轻巧、模块化并且有对用户友好的配置格式而广受欢迎。Detectify 使用 Google BigQuery 分析了从 GitHub 下载的近 50000 个不重复的 Nginx 配置文件。

本文主要关注以下常见的 Nginx 错误配置:

  • 根目录位置丢失

  • off-by-slash

  • 不安全的变量使用

  • 原始后端响应读取

  • merge_slashes设置为 off

1根目录位置丢失
server {        root /etc/nginx;
location /hello.txt { try_files $uri $uri/ =404; proxy_pass http://127.0.0.1:8080/; }}

root 指令指定 Nginx 的根文件夹。在上面的示例中,根文件夹是/etc/nginx,这意味着我们可以访问该文件夹中的文件。上面的配置没有针对/ (location / {...})的位置,只有/hello.txt的位置。因此,root 指令会被设置为全局,这意味着对/的请求会将你带到本地路径/etc/nginx

GET /nginx.conf这样简单的请求都能显示存储在 /etc/nginx/nginx.conf中 Nginx 配置文件的内容。如果将根设置为/etc,则对/nginx/nginx.confGET请求将显示配置文件。在某些情况下,访问者可能会访问其他配置文件、访问日志甚至 HTTP 基本身份验证的加密凭据。

在我们收集的近 50000 个 Nginx 配置文件中,最常见的根路径如下:


经常配置错误的 Nginx 根路径

2off-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 演讲“Breaking Parser Logic!”中让这项技术广为人知。

https://i.blackhat.com/us-18/Wed-August-8/us-18-Orange-Tsai-Breaking-Parser-Logic-Take-Your-Path-Normalization-Off-And-Pop-0days-Out-2.pdf

在这个演讲中,他展示了如何结合一条缺少尾斜杠的location指令与一条alias指令,来读取 Web 应用程序的源代码。鲜为人知的是,它还可以与其他指令(例如proxy_pass)一起使用。我们来分解一下究竟发生了什么事情,以及为什么它能起作用。

location /api {                proxy_pass http://apiserver/v1/;        }

如果一个 Nginx 服务器运行能在 server 访问的以下配置,则可以假定访问者只能访问http://apiserver/v1/下的路径。

http://server/api/user -> http://apiserver/v1//user

当请求http://server/api/user时,Nginx 将首先规范化 URL。然后,它会查看前缀 /api是否与 URL 匹配,本例中是匹配的。

然后,服务器从 URL 中删除该前缀,保留/user路径。再将此路径添加到proxy_passURL 中,从而得到最终 URL http://apiserver/v1//user

请注意,这个 URL 中存在双斜杠,因为 location 指令不以单斜杠结尾,并且proxy_pass URL 路径以单斜杠结尾。大多数 Web 服务器会将http://apiserver/v1//user标准化为http://apiserver/v1/user,这意味着即使配置错误,所有内容仍将按预期运行,并且可能不会引起注意。请求http://server/api../可以利用这种错误配置,这将导致 Nginx 请求 URL http://apiserver/v1/../,其标准化为http://apiserver/。这可能产生的影响取决于利用这种错误配置可以达到的效果。例如,这可能导致 Apache 服务器状态通过 URL http://server/api../server-status公开,或者可能让不希望公开访问的路径可访问。

Nginx 服务器配置错误的一个迹象是,当 URL 中的一个斜杠被删除时,服务器仍会返回相同的响应。例如,如果http://server/api/userhttp://server/apiuser返回相同的响应,则服务器可能容易受到攻击。这将导致发送以下请求:

http://server/api/user -> http://apiserver/v1//userhttp://server/apiuser -> http://apiserver/v1/user
3不安全的变量使用

一些框架、脚本和 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结尾的 PHP 解释器,即使该文件在磁盘上不存在。这是 Nginx 创建的“陷阱和常见错误”文档中提到的,在许多 Nginx 配置中都常见的错误。

https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#passing-uncontrolled-requests-to-php?fileGuid=xVX6hcx8WXCYPVGd

如果这个 PHP 脚本试图基于SCRIPT_NAME定义一个基本 URL,则将发生 XSS。


if(basename($_SERVER['SCRIPT_NAME']) ==basename($_SERVER['SCRIPT_FILENAME'])) echo dirname($_SERVER['SCRIPT_NAME']);
?>
GET /index.php/<script>alert(1)script>/index.phpSCRIPT_NAME = /index.php/<script>alert(1)script>/index.php
 使用 $uri 可导致 CRLF 注入

与 Nginx 变量有关的另一个错误配置是使用$uri$document_uri代替$request_uri$uri$document_uri包含标准化的 URI,而 Nginx 中的normalization包括对 URI 解码的 URL。Volema 发现,在 Nginx 配置中创建重定向时经常会使用$uri,结果导致 CRLF 注入。

一个易受攻击的 Nginx 配置的示例如下:

location / {return 302 https://example.com$uri;}

HTTP 请求的换行符为\r(回车)和\n(换行)。对换行符进行 URL 编码将导致以下字符表示形式%0d%0a。如果将这些字符包含在对配置错误的服务器的一个请求中(例如http://localhost/%0d%0aDetectify:%20clrf),则该服务器将使用一个名为Detectify的新标头进行响应,因为 $uri 变量包含 URL 解码的换行符。

HTTP/1.1 302 Moved TemporarilyServer: nginx/1.19.3Content-Type: text/htmlContent-Length: 145Connection: keep-aliveLocation: https://example.com/Detectify: clrf
 Any 变量

在某些情况下,用户提供的数据可以视为 Nginx 变量。目前尚不清楚为什么会发生这种情况,但如这份 H1 报告所示,这种情况并不罕见或不容易测试。如果搜索错误消息,我们可以看到它是在 SSI 过滤器模块中找到的,表明这是由 SSI 引起的。

https://hackerone.com/reports/370094?fileGuid=xVX6hcx8WXCYPVGd

一种测试方法是设置一个引用标头值:

$ curl -H ‘Referer: bar’ http://localhost/foo$http_referer | grep ‘foobar’

我们扫描了这种错误配置,发现了几个实例,用户可以在其中打印 Nginx 变量的值。我们发现易受攻击实例的数量有所下降,这可能表明这个漏洞已经做了修补。

4原始后端响应读取

使用 Nginx 的proxy_pass,可以拦截后端创建的错误和 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,proxy_intercept_errors 将提供一个自定义响应。在上面的 uWSGI 应用程序中,我们将发送一个500 Error,Nginx 将拦截该错误。

proxy_hide_header 可以自解释;它将从客户端隐藏任何指定的 HTTP 标头。

如果我们发送一个普通的 GET 请求,则 Nginx 将返回:

HTTP/1.1 500 Internal Server ErrorServer: nginx/1.10.3Content-Type: text/htmlContent-Length: 34Connection: close

但是,如果我们发送一个无效的 HTTP 请求,例如:

GET /? XTTP/1.1Host: 127.0.0.1Connection: close

我们将收到以下答复:

XTTP/1.1 500 ErrorContent-Type: text/htmlSecret-Header: secret-infoSecret info, should not be visible!
5merge_slashes 设置为 off

默认情况下,merge_slashes 指令设置为“on”,这是一种将两个或多个正斜杠压缩为一个的机制,因此///将变为/。如果 Nginx 用作反向代理,并且被代理的应用程序容易受到本地文件包含内容的影响,则在请求中使用额外的斜杠可能会留出恶意利用空间。

http://nginx.org/en/docs/http/ngx_http_core_module.html#merge_slashes?fileGuid=xVX6hcx8WXCYPVGd

我们发现 33 个 Nginx 配置文件的merge_slashes设置为“off”。

6自己尝试一下

我们创建了一个 GitHub 存储库,你可以在其中使用 Docker 来设置你自己的易受攻击的 Nginx 测试服务器,以及本文中讨论的一些错误配置,然后尝试自己找到它们。

https://github.com/detectify/vulnerable-nginx?fileGuid=xVX6hcx8WXCYPVGd

7总结

Nginx 是一个非常强大的 Web 服务器平台,很好理解为什么它会被广泛使用。但是,灵活的配置意味着你更容易犯错误,而这些错误可能会对安全性产生影响。请不要使用这些常见的错误配置,以免攻击者轻易地入侵你的网站。

原文链接:

https://blog.detectify.com/2020/11/10/common-nginx-misconfigurations/?fileGuid=xVX6hcx8WXCYPVGd


你也「在看」吗?👇

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/110817