Common NGINX Misconfigurations

Veja também em vídeo aqui:
https://youtu.be/0Kn9RmUByXQ
Aposto que você já teve que criar algum arquivo de rotas usando NGINX, seja para distribuir assets de uma pasta específica, seja para redirecionar o tráfego para outra aplicação interna.
Contudo, todavia, entretanto, se você acabar comentendo alguns destes 3 erros clássicos, você pode acabar com um set de vulnerabilidades bem facinho aí.
1 - Missing Root
Todo arquivo de NGINX pode ter um ponto de partida onde ele vai procurar por arquivos. Para isto, utilizamos o root:
server {
listen 80;
server_name localhost;
root /etc/nginx; # <-- AQUI
location /home/ {
alias /usr/share/nginx/html/;
index home.html home.htm;
try_files $uri $uri/ =404;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Porém perceba que em nossas configurações, não temos nenhum location que aponta para /.
A falta desta configuração faz com que o NGINX tenha a permissão de entregar qualquer arquivo que esteja dentro da pasta definida no root (/etc/nginx).
Ou seja, se você fizer uma request para `/nginx.conf`, o NGINX vai procurar por este arquivo dentro do diretório root. Se encontrar, vai entregar para você.
=== REQUEST ===
curl http://localhost/nginx.conf
=== RESPONSE ===
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
# include /etc/nginx/conf.d/*.conf;
include /etc/nginx/conf.d/server.conf;
}
Para corrigir este problema, basta definir uma rota raiz. Ela pode redirecionar para o index do site ou outra página que deseje.
server {
listen 80;
server_name localhost;
root /etc/nginx;
location / { # <-- AQUI
return 302 https://my-site-index.com;
}
location /home/ {
alias /usr/share/nginx/html/;
index home.html home.htm;
try_files $uri $uri/ =404;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
2 - Alias Traversal
Um erro bastante comum e inclusive fácil de cometermos é expormos os arquivos do servidor por causa da falta de um /.
Veja a configuração a seguir:
server {
listen 80;
server_name localhost;
location /health {
return 200 "healthy\n";
add_header Content-Type text/plain;
}
location /assets {
alias /var/assets/;
}
location / {
root /usr/share/nginx/html;
index home.html home.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Justamente onde temos o /assets , estamos mapeando que todo request recebido neste path, devemos buscar por resources dentro de /var/assets/ .
Até aí tudo bem, mas o problema aqui é justamente usarmos /assets e não /assets/ .
A falta desta / ao final, permite que um atacante busque por outros arquivos no servidor, usando um traversal (../).
Com isso, deixamos nosso server vulnerável a ataques como este aqui:
curl http://mysite.com/assets../log/nginx/access.log
Onde o NGINX vai permitir que uma busca a nível mais alto na hierarquia de diretorios seja realizada, concendo acessos à outros arquivos na qual não deveriam ser expostos externamente.
Para corrigir isso, basta colocar uma / ao final:
# ❌ NOOOP
location /assets {
alias /var/assets/;
}
# ✅ YEEEP
location /assets/ {
alias /var/assets/;
}
3 - Unsafe $uri
O terceiro e um dos mais legais na minha opinião é você ser capaz de adicionar header qualquer na resposta de uma requisição via URL.
Simples:
Você monta uma URL maliciosa.
Manda para a vítima (qualquer técnica de phishing).
Ela clica.
Faz um request para o server.
O server responde com seu Header customizado.
Se a aplicação confia nos headers de resposta do servidor e faz algo com ela, boooom 💀.
Veja a configuração a seguir:
server {
listen 80;
server_name localhost;
root /usr/share/nginx/html/;
location / {
return 302 http://localhost/v2$uri;
}
location /v2/ {
return 200 "Hello\n";
add_header Content-Type text/plain;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
Perceba onde mapeamos o location / estamos redirecionando todos para a versão 2 do nosso site ou api (beeem comum aqui). Porém contatenamos tudo que o usuário colocar na URL, para preservar paths, query strings, etc (com o $uri ).
O problema aqui é justamente o uso do $uri e abertura para um CRLF Injection.
Se o atacante enviar este link para a vítima:
https://mysite.com/%0d%0aSet-Cookie:%20session=12345
O servidor vai responder que deve criar este cookie session=12345 no navegador da vítima.
Porque isto acontece?
Este %0d%0a é uma quebra de linha. Ao montar a resposta, o pacote HTTP vai ficar assim:
HTTP/2 302 Found
Location: http://localhost/v2/
Set-Cookie: session=12345
E isso aconteceu porque:
Vítima abre o link
https://mysite.com/%0d%0aSet-Cookie:%20session=12345Servidor recebe requisição.
Servidor encontra rota no NGINX (
location /)Servidor ve que precisa redirecionar para v2 mantendo o path etc (
return 302 http://localhost/v2$uri;)Todo redirect (301, 302) seta um header location. Neste caso, vai definir este header com o redirecionamento, que é
http://localhost/v2$uriMas para redirecionar, precisa colocar o valor da variável
$uri.Ao substituir a variável, fica assim:
http://localhost/v2/%0d%0aSet-Cookie:%20session=12345Por estar usando a variável
$uri, precisa parsear os caracteres especiais, no caso de%0d%0a, é uma nova linha.No protocolo HTTP, uma nova linha é... UM HEADER NOVO.
É adicionado a nova linha
Set-Cookie:%20session=12345, que vira um novo header.Este header é devolvido na resposta.
O navegador lê os headers da resposta.
Vê um header
Set-Cookiee cria o cookie.
Ou seja, se sua aplicação confia cegamente nas respostas da api e você possui esta config, possui uma vulnerabilidade que pode ser explorada.
Para corrigir isso, basta utilizar $request_uri e não $uri ou $document_uri.
Igual, não se esqueça de sanitizar os headers Location, uma vez que esta mesma vulnerabilidade pode estar presente em outros mecanismos de redirecionamento em sua infraestrutra.
References
Comments
Join the discussionNo comments yet. Be the first to comment.






