Nginx
Tip
Leer en oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.
Ontbrekende root location
Wanneer jy die Nginx-server konfigureer, speel die root directive ’n kritieke rol deur die basisdirektorie te definieer waarvandaan lêers bedien word. Oorweeg die voorbeeld hieronder:
server {
root /etc/nginx;
location /hello.txt {
try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1:8080/;
}
}
In hierdie konfigurasie is /etc/nginx aangewys as die root-gids. Hierdie opstelling laat toegang toe tot lêers binne die gespesifiseerde root-gids, soos /hello.txt. Dit is egter belangrik om op te let dat slegs ’n spesifieke location (/hello.txt) gedefinieer is. Daar is geen konfigurasie vir die root-locatie (location / {...}) nie. Hierdie weglating beteken dat die root-direktief globaal van toepassing is, wat versoeke na die root-pad / in staat stel om lêers onder /etc/nginx te bereik.
’n Kritieke sekuriteitsoorweging spruit uit hierdie konfigurasie. ’n Eenvoudige GET versoek, soos GET /nginx.conf, kan sensitiewe inligting blootstel deur die Nginx-konfigurasielêer by /etc/nginx/nginx.conf te bedien. Om die root op ’n minder sensitiewe gids soos /etc te stel, kan hierdie risiko verminder, maar dit kan steeds onbedoelde toegang tot ander kritieke lêers toelaat, insluitend ander konfigurasielêers, toegangsloglêers, en selfs geënkripteerde geloofsbriewe wat vir HTTP basic authentication gebruik word.
Alias LFI Misconfigurasie
In die konfigurasielêers van Nginx is ’n noukeurige inspeksie van die “location” directives nodig. ’n Kwesbaarheid wat bekend staan as Local File Inclusion (LFI) kan per ongeluk geïntroduseer word deur ’n konfigurasie wat soos die volgende lyk:
location /imgs {
alias /path/images/;
}
Hierdie konfigurasie is vatbaar vir LFI attacks omdat die bediener versoeke soos /imgs../flag.txt interpreteer as ’n poging om lêers buite die beoogde gids te bereik, wat effektief opgelos word na /path/images/../flag.txt. Hierdie fout laat attackers toe om lêers vanaf die bediener se lêerstelsel op te haal wat nie via die web toeganklik behoort te wees nie.
Om hierdie kwesbaarheid te verlig, moet die konfigurasie aangepas word om:
location /imgs/ {
alias /path/images/;
}
Meer inligting: https://www.acunetix.com/vulnerabilities/web/path-traversal-via-misconfigured-nginx-alias/
Accunetix-toetse:
alias../ => HTTP status code 403
alias.../ => HTTP status code 404
alias../../ => HTTP status code 403
alias../../../../../../../../../../../ => HTTP status code 400
alias../ => HTTP status code 403
Onveilige padbeperking
Kyk na die volgende bladsy om te leer hoe om directives soos te bypass:
location = /admin {
deny all;
}
location = /admin/ {
deny all;
}
Proxy / WAF Protections Bypass
Onveilige gebruik van veranderlikes / HTTP Request Splitting
Caution
Kwetsbare veranderlikes
$urien$document_uri — dit kan reggestel word deur hulle met$request_urite vervang.A regex kan ook kwetsbaar wees soos:
location ~ /docs/([^/])? { … $1 … }- Vulnerable
location ~ /docs/([^/\s])? { … $1 … }- Not vulnerable (checking spaces)
location ~ /docs/(.*)? { … $1 … }- Not vulnerable
’n Kwetsbaarheid in Nginx-konfigurasie word deur die onderstaande voorbeeld geïllustreer:
location / {
return 302 https://example.com$uri;
}
Die karakters \r (Carriage Return) en \n (Line Feed) dui nuwe reëlkarakters in HTTP requests aan, en hul URL-gekodeerde vorme word voorgestel as %0d%0a. Om hierdie karakters in ’n request in te sluit (bv. http://localhost/%0d%0aDetectify:%20clrf) na ’n verkeerd gekonfigureerde server, sal daartoe lei dat die server ’n nuwe header met die naam Detectify uitreik. Dit gebeur omdat die $uri-variabele die URL-gekodeerde new line-karakters dekodeer, wat lei tot ’n onverwagte header in die response:
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
Lees meer oor die risiko’s van CRLF injection en response splitting by https://blog.detectify.com/2019/06/14/http-response-splitting-exploitations-and-mitigations/.
Also this technique is explained in this talk with some vulnerable examples and dectection mechanisms. Byvoorbeeld, om hierdie misconfigurasie vanuit ’n blackbox-perspektief te ontdek, kan jy hierdie versoeke stuur:
https://example.com/%20X- Any HTTP codehttps://example.com/%20H- 400 Bad Request
As dit kwesbaar is, sal die eerste teruggee omdat “X” enige HTTP-metode is, en die tweede sal ’n fout teruggee omdat H nie ’n geldige metode is nie. Die bediener sal dus iets soos ontvang: GET / H HTTP/1.1 en dit sal die fout veroorsaak.
Nog opsporingsvoorbeelde kan wees:
http://company.tld/%20HTTP/1.1%0D%0AXXXX:%20x- Any HTTP codehttp://company.tld/%20HTTP/1.1%0D%0AHost:%20x- 400 Bad Request
Party kwesbare konfigurasies wat in daardie praatjie aangebied is, was:
- Let op hoe
$uriongewysig in die finale URL gestel word
location ^~ /lite/api/ {
proxy_pass http://lite-backend$uri$is_args$args;
}
- Let op hoe
$uriweer in die URL voorkom (hierdie keer binne ’n parameter)
location ~ ^/dna/payment {
rewrite ^/dna/([^/]+) /registered/main.pl?cmd=unifiedPayment&context=$1&native_uri=$uri break;
proxy_pass http://$back;
- Nou in AWS S3
location /s3/ {
proxy_pass https://company-bucket.s3.amazonaws.com$uri;
}
Enige veranderlike
Daar is ontdek dat gebruikersverskafde data moontlik as ’n Nginx variable behandel kan word onder sekere omstandighede. Die oorsaak van hierdie gedrag bly ietwat onduidelik, en dit is nie skaars nie maar ook nie maklik om te verifieer nie. Hierdie anomalie is beklemtoon in ’n sekuriteitsverslag op HackerOne, wat besigtig kan word here. Verdere ondersoek na die foutboodskap het gelei tot die identifisering van die verskynsel binne die SSI filter module of Nginx’s codebase, wat Server Side Includes (SSI) as die grondliggende oorsaak uitwys.
Om hierdie miskonfigurasie te ontdek, kan die volgende opdrag uitgevoer word, wat behels dat ’n Referer header gestel word om te toets of veranderlikes uitgeprint word:
$ curl -H ‘Referer: bar’ http://localhost/foo$http_referer | grep ‘foobar’
Skanderings vir hierdie wankonfigurasie oor stelsels het verskeie voorbeelde getoon waar Nginx-veranderlikes deur ’n gebruiker vertoon kon word. Daar is egter ’n afname in die aantal kwesbare gevalle, wat daarop dui dat pogings om hierdie probleem te patch tot ’n mate suksesvol was.
Gebruik van try_files met $URI$ARGS veranderlikes
Die volgende verkeerde Nginx-konfigurasie kan lei tot ’n LFI vulnerability:
location / {
try_files $uri$args $uri$args/ /index.html;
}
In ons konfigurasie het ons die direktief try_files wat gebruik word om na die bestaan van lêers in ’n gespesifiseerde volgorde te kyk. Nginx sal die eerste een wat hy vind bedien. Die basiese sintaksis van die try_files direktief is soos volg:
try_files file1 file2 ... fileN fallback;
Nginx sal vir die bestaan van elk van die lêers in die gespesifiseerde volgorde kontroleer. As ’n lêer bestaan, sal dit onmiddellik bedien word. As geen van die gespesifiseerde lêers bestaan nie, sal die versoek aan die terugvalopsie deurgegee word, wat ’n ander URI of ’n spesifieke foutbladsy kan wees.
Wanneer jy egter $uri$args-veranderlikes in hierdie direktief gebruik, sal Nginx probeer om te soek na ’n lêer wat ooreenstem met die versoek-URI gekombineer met enige query string-argumente. Daarom kan ons hierdie konfigurasie uitbuit:
http {
server {
root /var/www/html/public;
location / {
try_files $uri$args $uri$args/ /index.html;
}
}
}
Met die volgende payload:
GET /?../../../../../../../../etc/passwd HTTP/1.1
Host: example.com
Met ons payload ontsnap ons die wortelgids (gedefinieer in die Nginx-konfigurasie) en laai die /etc/passwd-lêer. In debug logs kan ons waarneem hoe Nginx die lêers probeer:
...SNIP...
2025/07/11 15:49:16 [debug] 79694#79694: *4 trying to use file: "/../../../../../../../../etc/passwd" "/var/www/html/public/../../../../../../../../etc/passwd"
2025/07/11 15:49:16 [debug] 79694#79694: *4 try file uri: "/../../../../../../../../etc/passwd"
...SNIP...
2025/07/11 15:49:16 [debug] 79694#79694: *4 http filename: "/var/www/html/public/../../../../../../../../etc/passwd"
...SNIP...
2025/07/11 15:49:16 [debug] 79694#79694: *4 HTTP/1.1 200 OK
PoC teen Nginx wat die bogenoemde konfiguratie gebruik:

Raw backend response uitlees
Nginx bied ’n funksie deur proxy_pass wat die onderskep van foute en HTTP-headers wat deur die backend gegenereer word toelaat, met die doel om interne foutboodskappe en headers te verberg. Dit word bereik deurdat Nginx pasgemaakte foutbladsye bedien as reaksie op backend-foute. Tog ontstaan probleme wanneer Nginx ’n ongeldige HTTP request teëkom. So ’n request word soos ontvang na die backend deurgegee, en die backend se raw response word dan direk aan die client gestuur sonder Nginx se ingryping.
Oorweeg ’n voorbeeldscenario wat ’n uWSGI application betrek:
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!"]
Om dit te bestuur, word spesifieke direkteiewe in die Nginx-konfigurasie gebruik:
http {
error_page 500 /html/error.html;
proxy_intercept_errors on;
proxy_hide_header Secret-Header;
}
- proxy_intercept_errors: Hierdie direktief laat Nginx toe om ’n pasgemaakte respons te lewer vir backend-responses met ’n statuskode groter as 300. Dit verseker dat, vir ons voorbeeld uWSGI-toepassing, ’n
500 Error-respons afgevang en deur Nginx hanteer word. - proxy_hide_header: Soos die naam aandui, verberg hierdie direktief gespesifiseerde HTTP-headers van die kliënt, wat privaatheid en sekuriteit verbeter.
Wanneer ’n geldige GET-versoek gemaak word, verwerk Nginx dit normaalweg en stuur ’n standaard foutrespons sonder om enige geheime headers bekend te maak. ’n Ongeldige HTTP-versoek omseil egter hierdie meganisme, wat lei tot die blootstelling van rou backend-responses, insluitend geheime headers en foutboodskappe.
merge_slashes gestel op off
Standaard is Nginx se merge_slashes directive gestel op on, wat meerdere vorentoe-slashes in ’n URL saamdruk tot ’n enkele slash. Hierdie funksie, hoewel dit URL-verwerking vereenvoudig, kan per ongeluk kwesbaarhede in toepassings agter Nginx verberg, veral dié vatbaar vir local file inclusion (LFI)-aanvalle. Sekuriteitseksperte Danny Robinson and Rotem Bar het die potensiële risiko’s wat met hierdie standaardgedrag gepaardgaan beklemtoon, veral wanneer Nginx as ’n reverse-proxy optree.
Om sulke risiko’s te verminder, word dit aanbeveel om die merge_slashes directive af te skakel vir toepassings wat aan hierdie kwesbaarhede onderhewig is. Dit verseker dat Nginx versoeke aan die toepassing deurgee sonder om die URL-struktuur te verander, en sodoende nie onderliggende sekuriteitsprobleme te verberg nie.
For more information check Danny Robinson and Rotem Bar.
Maclicious Response Headers
Soos getoon in this writeup, is daar sekere headers wat, indien teenwoordig in die respons van die webbediener, die gedrag van die Nginx-proxy sal verander. Jy kan dit in the docs nagaan:
X-Accel-Redirect: Dui Nginx aan om ’n versoek intern te herlei na ’n gespesifiseerde ligging.X-Accel-Buffering: Beheer of Nginx die respons moet buffer of nie.X-Accel-Charset: Stel die karakterstel vir die respons wanneer X-Accel-Redirect gebruik word.X-Accel-Expires: Stel die vervaltyd vir die respons wanneer X-Accel-Redirect gebruik word.X-Accel-Limit-Rate: Beperk die oordragtempo vir responses wanneer X-Accel-Redirect gebruik word.
Byvoorbeeld, die header X-Accel-Redirect sal ’n interne redirect in die nginx veroorsaak. Dus, ’n nginx-konfigurasie met iets soos root / en ’n respons van die webbediener met X-Accel-Redirect: .env sal nginx laat die inhoud van /.env stuur (Path Traversal).
Default Value in Map Directive
In die Nginx configuration speel die map directive dikwels ’n rol in toegangsbeheer. ’n Algemene fout is om nie ’n default waarde te spesifiseer nie, wat tot ongemagtigde toegang kan lei. Byvoorbeeld:
http {
map $uri $mappocallow {
/map-poc/private 0;
/map-poc/secret 0;
/map-poc/public 1;
}
}
server {
location /map-poc {
if ($mappocallow = 0) {return 403;}
return 200 "Hello. It is private area: $mappocallow";
}
}
Sonder n default kan ’n kwaadwillige gebruiker sekuriteit omseil deur ’n ongedefinieerde URI binne /map-poc te besoek. The Nginx manual raai aan om ’n standaardwaarde te stel om sulke probleme te vermy.
DNS Spoofing Kwetsbaarheid
DNS spoofing teen Nginx is moontlik onder sekere omstandighede. As ’n aanvaller die DNS server wat deur Nginx gebruik word ken en sy DNS-navrae kan onderskep, kan hy DNS-rekords spoof. Hierdie metode is egter ondoeltreffend as Nginx gekonfigureer is om localhost (127.0.0.1) vir DNS-resolusie te gebruik. Nginx laat toe om ’n DNS server soos volg te spesifiseer:
resolver 8.8.8.8;
proxy_pass en internal Direktiewe
Die proxy_pass direktief word gebruik om versoeke na ander servers te herlei, hetsy intern of ekstern. Die internal direktief verseker dat sekere locaties slegs binne Nginx toeganklik is. Alhoewel hierdie direktiewe op sigself nie kwesbaarhede is nie, vereis hul konfigurasie noukeurige ondersoek om sekuriteitsprobleme te voorkom.
proxy_set_header Upgrade & Connection
As die nginx-server gekonfigureer is om die Upgrade en Connection headers deur te gee, kan ’n h2c Smuggling attack uitgevoer word om toegang tot protected/internal endpoints te kry.
Caution
Hierdie kwesbaarheid sou ’n aanvaller toelaat om ’n direkte verbinding met die
proxy_passendpoint te vestig (http://backend:9999in hierdie geval) waarvan die inhoud nie deur nginx nagegaan sal word nie.
Example of vulnerable configuration to steal /flag from hier:
server {
listen 443 ssl;
server_name localhost;
ssl_certificate /usr/local/nginx/conf/cert.pem;
ssl_certificate_key /usr/local/nginx/conf/privkey.pem;
location / {
proxy_pass http://backend:9999;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;
}
location /flag {
deny all;
}
Warning
Let wel dat selfs al wys die
proxy_passna ’n spesifieke pad sooshttp://backend:9999/socket.io, sal die verbinding gevestig word methttp://backend:9999, sodat jy enige ander pad binne daardie interne eindpunt kan kontak. Dit maak dus nie saak of ’n pad in die URL van proxy_pass gespesifiseer is nie.
HTTP/3 QUIC-module afgeleë DoS & leak (2024)
Gedurende 2024 het nginx CVE-2024-31079, CVE-2024-32760, CVE-2024-34161 en CVE-2024-35200 bekendgemaak wat toon dat ’n enkele vyandige QUIC-sessie werkersprosesse kan laat crash of memory leak wanneer die eksperimentele ngx_http_v3_module ingekompileer is en ’n listen ... quic socket blootgestel is. Geaffekteerde builds is 1.25.0–1.25.5 en 1.26.0, terwyl 1.27.0/1.26.1 die fixes bevat; die geheue-onthulling (CVE-2024-34161) vereis verder MTU’s groter as 4096 bytes om sensitiewe data aan die oppervlak te bring (besonderhede in die 2024 nginx advisory hieronder).
Recon & exploitation hints
- HTTP/3 is opt-in, dus scan vir
Alt-Svc: h3=":443"responses of brute-force UDP/443 QUIC handshakes; sodra dit bevestig is, fuzz die handshake en STREAM frames met customquiche-client/nghttp3payloads om worker crashes te veroorsaak en log leakage af te dwing. - Vinnig fingerprint die teiken se ondersteuning met:
nginx -V 2>&1 | grep -i http_v3
rg -n "listen .*quic" /etc/nginx/
TLS sessie-herstelo-omseiling van client cert auth (CVE-2025-23419)
In Februarie 2025 het ’n advies bekendgemaak dat nginx 1.11.4–1.27.3 gebou met OpenSSL toelaat om ’n TLS 1.3 sessie te hergebruik van een naamgebaseerde virtual host binne ’n ander, sodat ’n kliënt wat ’n sertifikaat-vrye host onderhandel het die ticket/PSK kan herpeel om in ’n vhost beskerm met ssl_verify_client on; in te spring en mTLS heeltemal te omseil. Die fout tree op wanneer verskeie virtual hosts dieselfde TLS 1.3 sessie-kas en tickets deel (sien die 2025 nginx advisory hieronder).
Aanvaller playbook
# 1. Create a TLS session on the public vhost and save the session ticket
openssl s_client -connect public.example.com:443 -sess_out ticket.pem
# 2. Replay that session ticket against the mTLS vhost before it expires
openssl s_client -connect admin.example.com:443 -sess_in ticket.pem -ign_eof
As die teiken kwesbaar is, voltooi die tweede handshake sonder om ’n kliëntsertifikaat voor te lê, en openbaar daarmee beskermde liggings.
Wat om te oudit
- Gemengde
server_nameblokke watssl_session_cache shared:SSLplusssl_session_tickets on;deel. - Admin/API blokke wat mTLS verwag maar gedeelde session cache/ticket-instellings van openbare hosts erfen.
- Automatisering wat TLS 1.3 session resumption globaal inskakel (bv. Ansible-rolle) sonder om vhost-isolasie in ag te neem.
HTTP/2 Rapid Reset weerbaarheid (CVE-2023-44487 gedrag)
Die HTTP/2 Rapid Reset attack (CVE-2023-44487) raak nginx steeds as operateurs keepalive_requests of http2_max_concurrent_streams bo die verstekwaardes opskuif: ’n aanvaller maak een HTTP/2-verbinding oop, oorstroom dit met duisende streams, en stuur onmiddellik RST_STREAM-frames sodat die koncurrentie-plafon nooit bereik word nie terwyl die CPU bly brand op die afbreeklogika. Nginx verstekwaardes (128 concurrent streams, 1000 keepalive requests) hou die blast radius klein; om daardie perke “substantially higher” te stoot maak dit maklik om workers uit te hong selfs vanaf ’n enkele kliënt (sien die F5 write-up hieronder).
Opsporingswenke
# Highlight risky knobs
rg -n "http2_max_concurrent_streams" /etc/nginx/
rg -n "keepalive_requests" /etc/nginx/
Gasheerrekenaars wat ongewonerlik hoë waardes vir daardie direktiewe openbaar, is ideale teikens: een HTTP/2-kliënt kan deur stroomskepping en onmiddellike RST_STREAM-rame herhaal om die CPU op volle kapasiteit te hou sonder om die gelyktydigheidslimiet te tref.
Probeer dit self
Detectify het ’n GitHub repository geskep waarin jy Docker kan gebruik om jou eie kwesbare Nginx-toetsbediener met sommige van die in hierdie artikel beskryfde miskonfigurasies op te stel en self te probeer om dit te vind!
https://github.com/detectify/vulnerable-nginx
Statiese analise-instrumente
gixy-ng & Gixy-Next & GIXY
- Gixy-Next (’n opgedateerde fork van GIXY) is ’n hulpmiddel om Nginx-konfigurasies te ontleed, met die doel om kwesbaarhede, onveilige direktiewe en riskante miskonfigurasies te vind. Dit vind ook miskonfigurasies wat prestasie beïnvloed en bespeur gemiste verhardingsgeleenthede, wat geoutomatiseerde foutopsporing moontlik maak.
- gixy-ng (die aktief onderhoude fork van GIXY) is ’n hulpmiddel om Nginx-konfigurasies te ontleed, met die doel om kwesbaarhede, onveilige direktiewe en riskante miskonfigurasies te vind. Dit vind ook miskonfigurasies wat prestasie beïnvloed en bespeur gemiste verhardingsgeleenthede, wat geoutomatiseerde foutopsporing moontlik maak.
Nginxpwner
Nginxpwner is ’n eenvoudige hulpmiddel om na algemene Nginx-miskonfigurasies en kwesbaarhede te soek.
Verwysings
- https://blog.detectify.com/2020/11/10/common-nginx-misconfigurations/
- http://blog.zorinaq.com/nginx-resolver-vulns/
- https://github.com/yandex/gixy/issues/115
- https://mailman.nginx.org/pipermail/nginx-announce/2024/GWH2WZDVCOC2A5X67GKIMJM4YRELTR77.html
- https://mailman.nginx.org/pipermail/nginx-announce/2025/NYEUJX7NCBCGJGXDFVXNMAAMJDFSE45G.html
- https://www.f5.com/company/blog/nginx/http-2-rapid-reset-attack-impacting-f5-nginx-products
Tip
Leer en oefen AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Leer en oefen GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Leer en oefen Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Ondersteun HackTricks
- Kyk na die subskripsie planne!
- Sluit aan by die 💬 Discord groep of die telegram groep of volg ons op Twitter 🐦 @hacktricks_live.
- Deel hacking truuks deur PRs in te dien na die HackTricks en HackTricks Cloud github repos.


