Nginx常见的错误配置
翻译自Common Nginx misconfigurations that leave your web server open to attack
Nginx是当前主流的Web服务。 以下是一些最常见的错误配置。
Missing root location
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.conf的GET请求将显示配置文件。 在某些情况下,可能会访问其他配置文件,访问日志甚至HTTP基本身份验证的加密凭据。
在我们收集的近50,000个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/;
}
}
借助Off-by-slash配置错误,由于缺少/,因此有可能沿路径上移一步。 Orange Tsai在Blackhat的演讲“ Breaking Parser Logic!”中使这项技术广为人知。 在本次演讲中,他展示了location指令与alias指令结合使用的缺失斜杠如何使读取Web应用程序的源代码成为可能。 鲜为人知的是,它还可以与其他指令(例如proxy_pass)一起使用。 让我们来分解一下正在发生的事情以及它为什么起作用。
location /api {
proxy_pass http://apiserver/v1/;
}
如果Nginx服务器可以访问以下配置,则可以假定只能访问http://apiserver/v1/下的路径。
http://server/api/user -> http://apiserver/v1//user
当请求http://server/api/user时,Nginx将首先规范化URL。 然后,它会查看前缀/api是否与URL匹配,在这种情况下,它与URL匹配。 然后,从URL中删除该前缀,因此保留/user路径。 然后将此路径添加到proxy_pass URL中,从而得到最终URL http://apiserver/v1//user。 请注意,URL中存在双斜杠,因为location指令不以斜杠结尾,并且proxy_pass URL路径以斜杠结尾。 大多数Web服务器会将http://apiserver/v1//user user标准化为http://apiserver/v1/user,这意味着即使配置错误,所有内容仍将按预期运行,并且可能不会引起注意。
通过请求http://server/api../可以利用这种错误配置,这将导致Nginx请求标准化为http://apiserver/v1/../的URL http://apiserver/。 这可能产生的影响取决于利用这种错误配置可以达到的效果。 例如,这可能导致Apache服务器状态通过URL http://server/api../server-status公开,或者可能使不希望公开访问的路径可访问。
Nginx服务器配置错误的一个迹象是,当URL中的斜杠被删除时,服务器仍会返回相同的响应。 例如,如果http://server/api/user和http://server/apiuser返回相同的响应,则服务器可能容易受到攻击。 这将导致发送以下请求:
http://server/api/user -> http://apiserver/v1//user
http://server/apiuser -> http://apiserver/v1/user
Unsafe variable use
一些框架、脚本和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创建的Pitfalls and Common Mistakes文档中罗列的许多Nginx错误配置中的一种。
如果PHP脚本试图基于SCRIPT_NAME定义基本URL,则将发生XSS。
<?php
if(basename($_SERVER['SCRIPT_NAME']) ==
basename($_SERVER['SCRIPT_FILENAME']))
echo dirname($_SERVER['SCRIPT_NAME']);
?>
GET /index.php/<script>alert(1)</script>/index.php
SCRIPT_NAME = /index.php/<script>alert(1)</script>/index.php
Usage of $uri can lead to CRLF Injection
与Nginx变量有关的另一个错误配置是使用$uri或$document_uri而不是$request_uri。 $uri和$document_uri包含标准化的URI,而Nginx中的标准化包括对URI进行解码的URL。 [Volema](http://blog.volema.com/nginx-insecurities.html#header:~:text=Case 2%3A rewrite with %24uri (%24document_uri)) 发现,在Nginx配置中创建重定向会导致CRLF注入时,通常使用$uri。
易受攻击的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 Temporarily
Server: nginx/1.19.3
Content-Type: text/html
Content-Length: 145
Connection: keep-alive
Location: https://example.com/
Detectify: clrf
通过https://blog.detectify.com/2019/06/14/http-response-splitting-exploitations-and-mitigations/了解有关CRLF注射和反应分裂的风险的更多信息。
Any variable
在某些情况下,用户提供的数据可以视为Nginx变量。 目前尚不清楚为什么会发生这种情况,但如本H1报告所示,这种情况并不罕见或不容易测试。 如果搜索错误消息,我们可以看到它在 SSI filter module中找到,从而表明这是由于SSI引起的。
测试方法如下:
$ curl -H ‘Referer: bar’ http://localhost/foo$http_referer | grep ‘foobar’
Raw backend response reading
使用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错误,Nginx将拦截该错误。
proxy_hide_header:可以隐藏任何指定的来自客户端的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 set to off
默认情况下,merge_slashes指令设置为on,这是一种将两个或多个正斜杠压缩为一个的机制,因此///将变为/。 如果Nginx用作反向代理,并且被代理的应用程序容易受到本地文件包含的影响,则在请求中使用额外的斜杠可能会留出利用空间。 Danny Robinson and Rotem Bar对此进行了详细描述。
Nginx常见的错误配置的更多相关文章
- Nginx常见502错误
1.配置错误因为nginx找不到php-fpm了,所以报错,一般是fastcgi_pass后面的路径配置错误了,后面可以是socket或者是ip:port2.资源耗尽lnmp架构在处理php时,ngi ...
- Nginx常见错误与问题之解决方法技术指南
Nginx常见错误与问题之解决方法技术指南. 安装环境: 系统环境:redhat enterprise 6.5 64bit 1.Nginx 常见启动错误 有的时候初次安装nginx的时候会报这样的 ...
- Centos 7 上使用nginx为Node.js配置反向代理时错误:(13: Permission denied) while connecting to upstream
错误来源:Centos 7 上使用nginx为Node.js配置反向代理时产生(13: Permission denied) while connecting to upstream的错误 nginx ...
- Nginx详解二十五:Nginx架构篇之Nginx常见的问题
Nginx常见的问题 1.相同server_name多个虚拟主机优先级访问,是按读取文件的优先级来排序 在/opt/app/下准备3个code文件夹,下面放入3个html文件,里面的内容分别是code ...
- nginx安装升级及配置详解
1.简介 2.安装配置 3.配置文件介绍 4.启动.停止.平滑重启.升级 一.Nginx简介 Nginx(engine x)是俄罗斯人Igor Sysoev编写的一款高性能的http和反向代理服务器. ...
- nginx “403 Forbidden” 错误的原因及解决办法
nginx 的 403 Forbidden errors 表示你在请求一个资源文件但是nginx不允许你查看. 403 Forbidden 只是一个HTTP状态码,像404,200一样不是技术上的错误 ...
- Nginx常见的安装方式
Nginx常见的安装方式 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Nginx概述 Nginx的安装版本分为开发版.稳定版和过期版, Nginx安装可以使用yum或源码安装 ...
- Nginx中虚拟主机配置
一.Nginx中虚拟主机配置 1.基于域名的虚拟主机配置 1.修改宿主机的hosts文件(系统盘/windows/system32/driver/etc/HOSTS) linux : vim /etc ...
- Nginx入门--从核心配置与动静分离开始
写在前面 优化我们项目,服务器部署,不仅仅可以是分布式,Nginx一样可以通过动静分离,负载均衡来减轻我们服务器的压力.Nginx的知识链,学习周期相对比较长,博主也是刚刚入门,这篇就先从实现基础的动 ...
随机推荐
- c++ 向上取整和向下取整
在c++ 中: ceil()表示向上取整 floor()表示向下取整 当然,这很显然对浮点数很好用. 但如果两个int类型的数想要向上取整呢? 我们用 (n-1)/m+1 来表示即可.
- Codeforces Round #496 (Div. 3) D. Polycarp and Div 3 (数论)
题意:给你一个巨长无比的数,你可以将这个数划成任意多个部分,求这些部分中最多有多少个能被\(3\)整除. 题解:首先我们遍历累加每个位置的数字,如果某一位数或者累加和能被\(3\)整除(基础知识,不会 ...
- 金牛来到,福气来到——TcaplusDB新年放送
光阴似箭,2020转瞬间成为历史,牛年的钟声即将敲响,在此,TcaplusDB祝大家新的一年万事如意,牛年带给我们的福气,一定能让我们心想事成! 饮水思源,回顾过去的一年,我们深知,TcaplusDB ...
- spark 一、编程指南
总览 第一.每个spark 应用都有一个驱动程序去运行着主函数和再每个节点上的并行操作. spark提供了一个RDD(弹性分布式数据集)的数据集合,可以通过不同的节点并行操作运算,可以通过hdfs文件 ...
- Kubernets二进制安装(12)之部署Node节点服务的kube-Proxy
kube-proxy是Kubernetes的核心组件,部署在每个Node节点上,它是实现Kubernetes Service的通信与负载均衡机制的重要组件; kube-proxy负责为Pod创建代理服 ...
- spring-cloud-sleuth/zipkin
Spring Cloud Sleuth 一般的,一个分布式服务跟踪系统,主要有三部分:数据收集.数据存储和数据展示.根据系统大小不同,每一部分的结构又有一定变化.譬如,对于大规模分布式系统,数据存储可 ...
- Kconfig 配置文件编码规则
最早接触到Kconfig是在u-boot的移植过程中.所今天来好好学习一下如何编写一个符合Kconffigde 配置文件.Kbuild或者是Kconfig的中文翻译意思是内核配置/构建系统.他最早出自 ...
- OKR vs KPI
OKR vs KPI refs xgqfrms 2012-2020 www.cnblogs.com 发布文章使用:只允许注册用户才可以访问!
- auto responsive rem
auto responsive rem 移动端适配 ;(function(win, lib) { var doc = win.document; var docEl = doc.documentEle ...
- Flutter FractionallySizedBox 设置维度比例 而不是固定的px
本周小部件 有时您的设计需要相对的维度. FractionallySizedBox允许您将子项的大小调整为总可用空间的一小部分. Scaffold( body: Center( child: Frac ...