Nginx
Tip
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
Відсутнє root location
Під час конфігурації сервера Nginx, root directive відіграє критичну роль, визначаючи базовий каталог, звідки подаються файли. Розгляньте приклад нижче:
server {
root /etc/nginx;
location /hello.txt {
try_files $uri $uri/ =404;
proxy_pass http://127.0.0.1:8080/;
}
}
У цій конфігурації /etc/nginx призначено як кореневий каталог. Така настройка дозволяє отримувати доступ до файлів у вказаному кореневому каталозі, наприклад /hello.txt. Однак важливо зауважити, що визначено тільки конкретне місце (/hello.txt). Немає конфігурації для кореневого шляху (location / {...}). Це упущення означає, що директива root застосовується глобально, дозволяючи запитам до кореневого шляху / отримувати доступ до файлів під /etc/nginx.
З цією конфігурацією виникає критичне питання безпеки. Простий GET запит, наприклад GET /nginx.conf, може розкрити конфіденційну інформацію, подавши конфігураційний файл Nginx, що знаходиться за адресою /etc/nginx/nginx.conf. Встановлення root у менш чутливий каталог, наприклад /etc, може зменшити цей ризик, але все одно може дозволити небажаний доступ до інших критичних файлів, включаючи інші конфігураційні файли, журнали доступу та навіть зашифровані облікові дані, що використовуються для базової HTTP-аутентифікації.
Alias LFI Misconfiguration
У файлах конфігурації Nginx варто ретельно перевіряти директиви “location”. Упущення може призвести до вразливості, відомої як Local File Inclusion (LFI), яка може бути ненавмисно введена через конфігурацію, схожу на наступну:
location /imgs {
alias /path/images/;
}
Ця конфігурація уразлива до LFI-атак через те, що сервер інтерпретує запити на кшталт /imgs../flag.txt як спробу доступу до файлів поза передбаченим каталогом, фактично резольвуючи їх у /path/images/../flag.txt. Ця вразливість дозволяє зловмисникам отримувати файли з файлової системи сервера, які не повинні бути доступні через веб.
Щоб пом’якшити цю вразливість, конфігурацію слід змінити так:
location /imgs/ {
alias /path/images/;
}
Більше інформації: https://www.acunetix.com/vulnerabilities/web/path-traversal-via-misconfigured-nginx-alias/
Accunetix тести:
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
Небезпечне обмеження шляху
Перегляньте наступну сторінку, щоб дізнатися, як обійти директиви, такі як:
location = /admin {
deny all;
}
location = /admin/ {
deny all;
}
Proxy / WAF Protections Bypass
Небезпечне використання змінних / HTTP Request Splitting
Caution
Уразливі змінні
$uriта$document_uri — це можна виправити, замінивши їх на$request_uri.Регулярний вираз також може бути вразливим, наприклад:
location ~ /docs/([^/])? { … $1 … }- Vulnerable
location ~ /docs/([^/\s])? { … $1 … }- Not vulnerable (checking spaces)
location ~ /docs/(.*)? { … $1 … }- Not vulnerable
Нижче наведено приклад вразливості в конфігурації Nginx:
location / {
return 302 https://example.com$uri;
}
Символи \r (Carriage Return) та \n (Line Feed) позначають символи нового рядка в HTTP-запитах, а їх 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
Дізнайтеся більше про ризики CRLF injection та response splitting за адресою 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. Наприклад, щоб виявити цю неконфігурацію з точки зору blackbox, ви можете виконати такі запити:
https://example.com/%20X- Будь-який HTTP кодhttps://example.com/%20H- 400 Bad Request
Якщо вразливий, перший повернеться, оскільки “X” — це будь-який HTTP method, а другий поверне помилку, оскільки H не є дійсним методом. Тож сервер отримає щось на кшталт: GET / H HTTP/1.1 і це спричинить помилку.
Інші приклади виявлення:
http://company.tld/%20HTTP/1.1%0D%0AXXXX:%20x- Будь-який HTTP кодhttp://company.tld/%20HTTP/1.1%0D%0AHost:%20x- 400 Bad Request
Деякі знайдені вразливі конфігурації, представлені в тій доповіді, були:
- Зверніть увагу, як
$uriвстановлено без змін у кінцевому URL
location ^~ /lite/api/ {
proxy_pass http://lite-backend$uri$is_args$args;
}
- Зверніть увагу, як знову
$uriприсутній у URL (цього разу всередині параметра)
location ~ ^/dna/payment {
rewrite ^/dna/([^/]+) /registered/main.pl?cmd=unifiedPayment&context=$1&native_uri=$uri break;
proxy_pass http://$back;
- Тепер у AWS S3
location /s3/ {
proxy_pass https://company-bucket.s3.amazonaws.com$uri;
}
Будь-яка змінна
Було виявлено, що дані, надані користувачем, за певних обставин можуть трактуватися як змінна Nginx. Причина такої поведінки залишається дещо невизначеною, проте це не рідкість і не завжди легко перевірити. Цю аномалію було висвітлено в security report на HackerOne, який можна переглянути here. Подальше розслідування повідомлення про помилку призвело до виявлення її появи в SSI filter module of Nginx’s codebase, що вказує на Server Side Includes (SSI) як на корінь проблеми.
Щоб виявити цю неправильну конфігурацію, можна виконати наступну команду, яка встановлює заголовок Referer для перевірки друку змінної:
$ curl -H ‘Referer: bar’ http://localhost/foo$http_referer | grep ‘foobar’
Сканування на наявність цієї неправильної конфігурації в різних системах виявило кілька випадків, коли користувач міг вивести змінні Nginx. Однак зменшення кількості уразливих інстансів свідчить про те, що зусилля з виправлення цієї проблеми були доволі успішними.
Використання try_files з $URI$ARGS змінними
Наведена нижче неправильна конфігурація Nginx може призвести до LFI-вразливості:
location / {
try_files $uri$args $uri$args/ /index.html;
}
У нашій конфігурації є директива try_files, яка використовується для перевірки існування файлів у вказаному порядку. Nginx віддасть перший знайдений. Базовий синтаксис директиви try_files такий:
try_files file1 file2 ... fileN fallback;
Nginx перевірятиме наявність кожного файлу в зазначеному порядку. Якщо файл існує, він буде негайно повернутий. Якщо жоден із зазначених файлів не існує, запит буде передано до резервного варіанту, який може бути іншим URI або певною сторінкою помилки.
Однак при використанні змінних $uri$args у цій директиві Nginx спробує знайти файл, що відповідає URI запиту, поєднаному з будь-якими аргументами query string. Тому ми можемо експлуатувати цю конфігурацію:
http {
server {
root /var/www/html/public;
location / {
try_files $uri$args $uri$args/ /index.html;
}
}
}
З наступним payload:
GET /?../../../../../../../../etc/passwd HTTP/1.1
Host: example.com
Використовуючи наш payload, ми вийдемо за межі кореневого каталогу (визначеного в конфігурації Nginx) і завантажимо файл /etc/passwd. У debug logs ми можемо спостерігати, як Nginx намагається звернутися до файлів:
...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 проти Nginx, використовуючи конфігурацію, згадану вище:

Зчитування сирої відповіді бекенду
Nginx пропонує можливість через proxy_pass, яка дозволяє перехоплювати помилки та HTTP-заголовки, що генеруються бекендом, з метою приховування внутрішніх повідомлень про помилки та заголовків. Це здійснюється тим, що Nginx повертає кастомні сторінки помилок у відповідь на помилки бекенду. Однак виникають складнощі, коли Nginx отримує некоректний HTTP-запит. Такий запит пересилається на бекенд як є, а сирa відповідь бекенду потім безпосередньо відправляється клієнту без втручання Nginx.
Розглянемо приклад сценарію з додатком 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;
}
- proxy_intercept_errors: Ця директива дозволяє Nginx повертати користувацьку відповідь для відповідей бекенда зі статус-кодом більшим за 300. Вона гарантує, що, у нашому прикладі з uWSGI application, відповідь
500 Errorбуде перехоплена та оброблена Nginx. - proxy_hide_header: Як випливає з назви, ця директива приховує вказані HTTP-заголовки від клієнта, підвищуючи приватність та безпеку.
Коли надходить дійсний GET запит, Nginx обробляє його звичайно, повертаючи стандартну помилкову відповідь без розкриття будь-яких секретних заголовків. Однак недійсний HTTP-запит обходить цей механізм, що призводить до витоку сирих відповідей бекенда, включно з секретними заголовками та повідомленнями про помилки.
merge_slashes встановлено в off
За замовчуванням директива merge_slashes Nginx встановлена в on, що стискає кілька слешів у URL до одного. Ця функція, хоч і спрощує обробку URL, може ненавмисно приховувати вразливості в додатках за Nginx, особливо ті, що вразливі до local file inclusion (LFI) атак. Експерти з безпеки Danny Robinson and Rotem Bar підкреслювали потенційні ризики, пов’язані з цією поведінкою за замовчуванням, особливо коли Nginx виступає як reverse-proxy.
Щоб зменшити такі ризики, рекомендується вимкнути директиву merge_slashes для додатків, схильних до цих вразливостей. Це гарантує, що Nginx пересилає запити до додатка без змін у структурі URL, не маскуючи тим самим основні проблеми безпеки.
Детальніше дивіться у Danny Robinson and Rotem Bar.
Maclicious заголовки відповіді
Як показано в цьому розборі, існують певні заголовки, які, якщо присутні в відповіді веб‑сервера, змінюють поведінку Nginx proxy. Ви можете перевірити їх в документації:
X-Accel-Redirect: вказує Nginx на внутрішнє перенаправлення запиту до вказаного місця.X-Accel-Buffering: керує тим, чи повинен Nginx буферизувати відповідь.X-Accel-Charset: встановлює набір символів для відповіді при використанні X-Accel-Redirect.X-Accel-Expires: встановлює термін дії відповіді при використанні X-Accel-Redirect.X-Accel-Limit-Rate: обмежує швидкість передавання відповіді при використанні X-Accel-Redirect.
Наприклад, заголовок X-Accel-Redirect спричиняє внутрішнє перенаправлення в nginx. Отже, наявність конфігурації nginx зі, наприклад, root / і відповіді від веб‑сервера з X-Accel-Redirect: .env змусить nginx віддати вміст /.env (Path Traversal).
Значення за замовчуванням у директиві map
У конфігурації Nginx директива map часто відіграє роль у контролі авторизації. Поширена помилка — не вказати значення default, що може призвести до несанкціонованого доступу. Наприклад:
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";
}
}
Без default, зловмисник може обійти захист, отримавши доступ до невизначеного URI в межах /map-poc. The Nginx manual радить встановити default value, щоб уникнути таких проблем.
DNS Spoofing Vulnerability
DNS spoofing проти Nginx можливий за певних умов. Якщо зловмисник знає DNS server, який використовує Nginx, і може перехоплювати його DNS queries, він може підробляти DNS-записи. Однак цей метод неефективний, якщо Nginx налаштовано використовувати localhost (127.0.0.1) для розв’язання DNS. Nginx дозволяє вказати DNS server таким чином:
resolver 8.8.8.8;
proxy_pass and internal Директиви
Директива proxy_pass використовується для перенаправлення запитів на інші сервери, як внутрішні, так і зовнішні. Директива internal гарантує, що певні локації доступні тільки в межах Nginx. Хоча самі по собі ці директиви не є вразливостями, їх конфігурацію слід уважно перевіряти, щоб запобігти проблемам із безпекою.
proxy_set_header Upgrade & Connection
Якщо nginx-сервер налаштований на передачу заголовків Upgrade та Connection, може бути виконана h2c Smuggling attack для отримання доступу до захищених/внутрішніх endpoints.
Caution
Ця вразливість дозволила б атакуючому встановити пряме з’єднання з
proxy_passendpoint (http://backend:9999у цьому випадку), вміст якого не буде перевірятися nginx.
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
Зверніть увагу, що навіть якщо
proxy_passвказує на конкретний шлях наприкладhttp://backend:9999/socket.io, з’єднання встановлюється зhttp://backend:9999, тож ви можете зв’язатися з будь-яким іншим шляхом всередині цієї внутрішньої кінцевої точки. Тому не має значення, чи вказано шлях у URL of proxy_pass.
HTTP/3 QUIC module — віддалений DoS & leak (2024)
У 2024 році Nginx розкрив CVE-2024-31079, CVE-2024-32760, CVE-2024-34161 та CVE-2024-35200, що показали: одна ворожа QUIC-сесія може спричиняти крах worker-процесів або викликати витік пам’яті, коли експериментальний модуль ngx_http_v3_module скомпільовано і відкрито сокет listen ... quic. Уразливі збірки: 1.25.0–1.25.5 та 1.26.0; виправлення включено у 1.27.0/1.26.1. Витік пам’яті (CVE-2024-34161) додатково вимагає MTUs більших за 4096 байт, щоб виявити конфіденційні дані (деталі — у advisory nginx 2024 року, наведений нижче).
Recon & exploitation hints
- HTTP/3 є опціональним, тож скануйте на наявність відповідей
Alt-Svc: h3=":443"або виконуйте brute-force UDP/443 QUIC handshakes; після підтвердження fuzz-те handshake і STREAM-фрейми кастомнимиquiche-client/nghttp3payloads, щоб спричинити крахи worker-процесів і змусити leak логів. - Quickly fingerprint target support with:
nginx -V 2>&1 | grep -i http_v3
rg -n "listen .*quic" /etc/nginx/
Обхід відновлення сесії TLS для client cert auth (CVE-2025-23419)
У бюлетені лютого 2025 року повідомили, що nginx 1.11.4–1.27.3, зібраний з OpenSSL, дозволяє повторно використовувати TLS 1.3 session з одного name-based virtual host в іншому, тож клієнт, який підключився до хоста без сертифіката, може replay the ticket/PSK, щоб потрапити в vhost, захищений ssl_verify_client on;, і повністю обійти mTLS. Баг спрацьовує, коли кілька virtual hosts ділять один TLS 1.3 session cache та tickets (див. 2025 nginx advisory нижче).
План дій атакувача
# 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
Якщо ціль вразлива, друге рукостискання завершується без представлення клієнтського сертифіката, відкриваючи захищені локації.
Що перевіряти
- Змішані
server_nameблоки, які спільно використовуютьssl_session_cache shared:SSLтаssl_session_tickets on;. - Admin/API блоки, що очікують mTLS, але успадковують shared session cache/ticket settings від публічних хостів.
- Automation, яка вмикає TLS 1.3 session resumption глобально (e.g., Ansible roles) без урахування vhost isolation.
HTTP/2 Rapid Reset resilience (CVE-2023-44487 behavior)
The HTTP/2 Rapid Reset attack (CVE-2023-44487) досі впливає на nginx, коли оператори збільшують keepalive_requests або http2_max_concurrent_streams понад значення за замовчуванням: атакуючий відкриває одне HTTP/2 з’єднання, заповнює його тисячами streams, а потім негайно відправляє RST_STREAM кадри, так що стеля concurrency ніколи не досягається, тоді як CPU продовжує витрачати ресурси на логіку tear-down. Значення за замовчуванням nginx (128 concurrent streams, 1000 keepalive requests) тримають масштаб впливу малим; суттєве підвищення цих меж робить тривіальним виснаження workers навіть від одного клієнта (див. F5 write-up, наведений нижче).
Поради щодо виявлення
# Highlight risky knobs
rg -n "http2_max_concurrent_streams" /etc/nginx/
rg -n "keepalive_requests" /etc/nginx/
Хости, які показують ненормально високі значення цих директив, є привабливими цілями: один HTTP/2-клієнт може повторно створювати потоки й миттєво відправляти RST_STREAM кадри, щоб утримувати CPU завантаженим без перевищення ліміту одночасних з’єднань.
Спробуйте самі
Detectify створила репозиторій на GitHub, де ви можете за допомогою Docker підняти власний уразливий тестовий сервер Nginx з деякими помилками конфігурації, описаними в цій статті, і спробувати знайти їх самостійно!
https://github.com/detectify/vulnerable-nginx
Інструменти статичного аналізу
GIXY
Gixy — це інструмент для аналізу конфігурації Nginx. Головна мета Gixy — запобігти небезпечним помилкам конфігурації та автоматизувати виявлення вразливостей.
Nginxpwner
Nginxpwner — простий інструмент для пошуку поширених помилок конфігурації Nginx та вразливостей.
Джерела
- 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
Вивчайте та практикуйте AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Вивчайте та практикуйте GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Вивчайте та практикуйте Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Підтримайте HackTricks
- Перевірте плани підписки!
- Приєднуйтесь до 💬 групи Discord або групи telegram або слідкуйте за нами в Twitter 🐦 @hacktricks_live.
- Діліться хакерськими трюками, надсилаючи PR до HackTricks та HackTricks Cloud репозиторіїв на github.
HackTricks

