high
⌄
ssl_protocols_weak
ssl_protocols содержит устаревшие протоколы: TLSv1 TLSv1.1 TLSv1.2
Проверка
Проверка устаревших SSL-протоколов
Решение
Отключите устаревшие протоколы TLS.
Фрагмент
demo.conf
http { # --- Нет client_max_body_size --- # --- Устаревшие SSL-протоколы --- ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers DES-CBC3-SHA:RC4-SHA:AES128-SHA; # --- Нет merge_slashes --- merge_slashes off;
high
⌄
ssl_ciphers_weak
ssl_ciphers содержит слабые шифры: DES-CBC3-SHA:RC4-SHA:AES128-SHA
Проверка
Проверка слабых SSL-шифров
Решение
Используйте современные шифры.
Фрагмент
demo.conf
http { # --- Нет client_max_body_size --- # --- Устаревшие SSL-протоколы --- ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers DES-CBC3-SHA:RC4-SHA:AES128-SHA; # --- Нет merge_slashes --- merge_slashes off; # --- error_log отключён ---
high
⌄
git_exposed
Возможен доступ к .git в server-блоке 'example.com www.example.com'
Проверка
Проверка доступа к .git
Решение
Добавьте 'location ~ /\.git/ { deny all; }' для блокировки доступа к репозиторию.
Фрагмент
demo.conf
server_name example.com www.example.com; # --- autoindex включён --- autoindex on; # --- .git открыт --- # (нет блокировки location ~ /\.git) # --- dotfiles открыты (.env, .htpasswd) --- # (нет location ~ /\.)
high
⌄
proxy_ip_disclosure
Блок с proxy_pass не защищен от раскрытия внутренних IP: 'location /'
Проверка
Проверка раскрытия внутренних IP-адресов
Решение
Добавьте 'proxy_redirect off;' или 'proxy_redirect default;' в блоки с proxy_pass для предотвращения раскрытия внутренних IP-адресов.
Фрагмент
demo.conf
# --- Дублирующиеся директивы --- root /var/www/html; root /var/www/site; # --- proxy_pass без схемы --- location / { proxy_pass backend:3000; proxy_set_header Host "var">$http_host; # host_spoofing }
high
⌄
proxy_ip_disclosure
Блок с proxy_pass не защищен от раскрытия внутренних IP: 'location /api/'
Проверка
Проверка раскрытия внутренних IP-адресов
Решение
Добавьте 'proxy_redirect off;' или 'proxy_redirect default;' в блоки с proxy_pass для предотвращения раскрытия внутренних IP-адресов.
Фрагмент
demo.conf
# --- Дублирующиеся директивы --- root /var/www/html; root /var/www/site; # --- proxy_pass без схемы --- location / { proxy_pass backend:3000; proxy_set_header Host "var">$http_host; # host_spoofing }
high
⌄
proxy_ip_disclosure
Блок с proxy_pass не защищен от раскрытия внутренних IP: 'location /internal'
Проверка
Проверка раскрытия внутренних IP-адресов
Решение
Добавьте 'proxy_redirect off;' или 'proxy_redirect default;' в блоки с proxy_pass для предотвращения раскрытия внутренних IP-адресов.
Фрагмент
demo.conf
# --- Дублирующиеся директивы --- root /var/www/html; root /var/www/site; # --- proxy_pass без схемы --- location / { proxy_pass backend:3000; proxy_set_header Host "var">$http_host; # host_spoofing }
high
⌄
proxy_ip_disclosure
Блок с proxy_pass не защищен от раскрытия внутренних IP: 'location /admin-panel'
Проверка
Проверка раскрытия внутренних IP-адресов
Решение
Добавьте 'proxy_redirect off;' или 'proxy_redirect default;' в блоки с proxy_pass для предотвращения раскрытия внутренних IP-адресов.
Фрагмент
demo.conf
# --- Дублирующиеся директивы --- root /var/www/html; root /var/www/site; # --- proxy_pass без схемы --- location / { proxy_pass backend:3000; proxy_set_header Host "var">$http_host; # host_spoofing }
high
⌄
proxy_ip_disclosure
Блок с proxy_pass не защищен от раскрытия внутренних IP: 'location /metrics'
Проверка
Проверка раскрытия внутренних IP-адресов
Решение
Добавьте 'proxy_redirect off;' или 'proxy_redirect default;' в блоки с proxy_pass для предотвращения раскрытия внутренних IP-адресов.
Фрагмент
demo.conf
# --- Дублирующиеся директивы --- root /var/www/html; root /var/www/site; # --- proxy_pass без схемы --- location / { proxy_pass backend:3000; proxy_set_header Host "var">$http_host; # host_spoofing }
high
⌄
root_alias_with_variable
Директива 'root' использует переменную: /var/www/$host
Проверка
Проверка 'root'/'alias' на использование переменных
Решение
Использование переменных в директивах 'root' или 'alias' может привести к уязвимостям обхода каталога (Path Traversal).
Фрагмент
demo.conf
# --- rewrite цикл --- rewrite ^/loop/(.*)$ /loop/"var">$1 last; # --- Переменная в root --- location /dynamic { root /var/www/"var">$host; } # --- valid_referers с none --- location /images/ { valid_referers none server_names;
high
⌄
git_exposed
Возможен доступ к .git в server-блоке 'secure.example.com'
Проверка
Проверка доступа к .git
Решение
Добавьте 'location ~ /\.git/ { deny all; }' для блокировки доступа к репозиторию.
Фрагмент
demo.conf
server_name example.com www.example.com; # --- autoindex включён --- autoindex on; # --- .git открыт --- # (нет блокировки location ~ /\.git) # --- dotfiles открыты (.env, .htpasswd) --- # (нет location ~ /\.)
high
⌄
missing_ssl_dhparam
Отсутствует 'ssl_dhparam' в SSL server-блоке ''
Проверка
Проверка наличия ssl_dhparam
Решение
Укажите сильные параметры Диффи-Хеллмана (ssl_dhparam) для защиты от атак.
Фрагмент
demo.conf
listen 443; # нет ssl server_name secure.example.com; ssl_certificate /etc/ssl/certs/example.com.pem; ssl_certificate_key /etc/ssl/private/example.com.key; # --- Нет ssl_dhparam --- # --- Нет ssl_stapling --- # --- Нет ssl_trusted_certificate --- # --- Нет limit_req/limit_conn ---
high
⌄
listen_443_no_ssl
listen без ssl: 443
Проверка
Проверка listen 443 без ssl
Решение
Добавьте ssl к listen 443.
Фрагмент
demo.conf
# ========================================= # SSL-сервер с проблемами # ========================================= server { listen 443; # нет ssl server_name secure.example.com; ssl_certificate /etc/ssl/certs/example.com.pem; ssl_certificate_key /etc/ssl/private/example.com.key; # --- Нет ssl_dhparam ---
high
⌄
proxy_ip_disclosure
Блок с proxy_pass не защищен от раскрытия внутренних IP: 'location /'
Проверка
Проверка раскрытия внутренних IP-адресов
Решение
Добавьте 'proxy_redirect off;' или 'proxy_redirect default;' в блоки с proxy_pass для предотвращения раскрытия внутренних IP-адресов.
Фрагмент
demo.conf
# --- Дублирующиеся директивы --- root /var/www/html; root /var/www/site; # --- proxy_pass без схемы --- location / { proxy_pass backend:3000; proxy_set_header Host "var">$http_host; # host_spoofing }
high
⌄
proxy_ip_disclosure
Блок с proxy_pass не защищен от раскрытия внутренних IP: 'location /api/'
Проверка
Проверка раскрытия внутренних IP-адресов
Решение
Добавьте 'proxy_redirect off;' или 'proxy_redirect default;' в блоки с proxy_pass для предотвращения раскрытия внутренних IP-адресов.
Фрагмент
demo.conf
# --- Дублирующиеся директивы --- root /var/www/html; root /var/www/site; # --- proxy_pass без схемы --- location / { proxy_pass backend:3000; proxy_set_header Host "var">$http_host; # host_spoofing }
high
⌄
git_exposed
Возможен доступ к .git в server-блоке 'example.com'
Проверка
Проверка доступа к .git
Решение
Добавьте 'location ~ /\.git/ { deny all; }' для блокировки доступа к репозиторию.
Фрагмент
demo.conf
server_name example.com www.example.com; # --- autoindex включён --- autoindex on; # --- .git открыт --- # (нет блокировки location ~ /\.git) # --- dotfiles открыты (.env, .htpasswd) --- # (нет location ~ /\.)
high
⌄
listen_servername_conflict
server1: None server2: None listen: 80 server_name: example.com
Проверка
Проверка конфликтов listen/server_name
Решение
Измените listen/server_name для устранения конфликта.
Фрагмент
demo.conf
# --- Переменная в root --- location /dynamic { root /var/www/"var">$host; } # --- valid_referers с none --- location /images/ { valid_referers none server_names; if ("var">$invalid_referer) { return 403; }
high
⌄
ssrf
http://$arg_target (переменная $arg_target в хосте/схеме)
Проверка
Проверка SSRF через proxy_pass
Решение
Замените переменную в host/scheme на фиксированное значение или используйте map с белым списком.
Фрагмент
demo.conf
proxy_set_header Host "var">$http_host; # host_spoofing } # --- SSRF через переменную в proxy_pass --- location /api/ { proxy_pass http://"var">$arg_target; } # --- HTTP Response Splitting --- location /redirect { return 302 https://example.com"var">$request_uri;
high
⌄
http_splitting
proxy_set_header … $http_host (может содержать \n/\r)
Проверка
Проверка HTTP Response Splitting
Решение
Не используйте $request_uri/$arg_*/$http_* в заголовках и редиректах напрямую — применяйте $uri или sanitize-переменную.
Фрагмент
demo.conf
root /var/www/site; # --- proxy_pass без схемы --- location / { proxy_pass backend:3000; proxy_set_header Host "var">$http_host; # host_spoofing } # --- SSRF через переменную в proxy_pass --- location /api/ { proxy_pass http://"var">$arg_target;
high
⌄
http_splitting
proxy_pass … $arg_target (может содержать \n/\r)
Проверка
Проверка HTTP Response Splitting
Решение
Не используйте $request_uri/$arg_*/$http_* в заголовках и редиректах напрямую — применяйте $uri или sanitize-переменную.
Фрагмент
demo.conf
proxy_set_header Host "var">$http_host; # host_spoofing } # --- SSRF через переменную в proxy_pass --- location /api/ { proxy_pass http://"var">$arg_target; } # --- HTTP Response Splitting --- location /redirect { return 302 https://example.com"var">$request_uri;
high
⌄
http_splitting
return … $request_uri (может содержать \n/\r)
Проверка
Проверка HTTP Response Splitting
Решение
Не используйте $request_uri/$arg_*/$http_* в заголовках и редиректах напрямую — применяйте $uri или sanitize-переменную.
Фрагмент
demo.conf
proxy_pass http://"var">$arg_target; } # --- HTTP Response Splitting --- location /redirect { return 302 https://example.com"var">$request_uri; add_header X-Custom "var">$http_referer; } # --- alias traversal --- location /files {
high
⌄
http_splitting
add_header … $http_referer (может содержать \n/\r)
Проверка
Проверка HTTP Response Splitting
Решение
Не используйте $request_uri/$arg_*/$http_* в заголовках и редиректах напрямую — применяйте $uri или sanitize-переменную.
Фрагмент
demo.conf
} # --- HTTP Response Splitting --- location /redirect { return 302 https://example.com"var">$request_uri; add_header X-Custom "var">$http_referer; } # --- alias traversal --- location /files { alias /var/www/uploads;
high
⌄
host_spoofing
proxy_set_header Host $http_host
Проверка
Проверка подделки Host-заголовка
Решение
Замените $http_host на $host в proxy_set_header Host.
Фрагмент
demo.conf
root /var/www/site; # --- proxy_pass без схемы --- location / { proxy_pass backend:3000; proxy_set_header Host "var">$http_host; # host_spoofing } # --- SSRF через переменную в proxy_pass --- location /api/ { proxy_pass http://"var">$arg_target;
high
⌄
return_bypasses_allow_deny
location /admin
Проверка
Проверка обхода allow/deny через return
Решение
Перенесите return в named location или используйте try_files; allow/deny не защищают от return в том же блоке.
Фрагмент
demo.conf
allow 192.168.0.0/16; proxy_pass http://backend; } # --- return обходит allow/deny --- location /admin { allow 10.0.0.0/8; deny all; return 200 "admin panel"; }
high
⌄
allow_without_deny
location /internal — нет deny all
Проверка
Проверка allow без deny all
Решение
Добавьте deny all; после директив allow.
Фрагмент
demo.conf
proxy_pass http://prometheus:9090; } location /nginx_status { stub_status; # нет allow/deny } # --- PHP FastCGI без try_files --- location ~ \.php$ { fastcgi_pass unix:/run/php/php-fpm.sock;
high
⌄
valid_referers_none
none server_names
Проверка
Проверка valid_referers none
Решение
Уберите none из valid_referers или используйте другой механизм защиты.
Фрагмент
demo.conf
root /var/www/"var">$host; } # --- valid_referers с none --- location /images/ { valid_referers none server_names; if ("var">$invalid_referer) { return 403; } root /var/www; }
high
⌄
resolver_external
8.8.8.8
Проверка
Проверка внешнего DNS resolver
Решение
Используйте локальный resolver (127.0.0.1) вместо внешних DNS-серверов.
Фрагмент
demo.conf
# --- error_log отключён --- error_log /dev/null; # --- Внешний резолвер --- resolver 8.8.8.8; # --- set_real_ip_from любой --- set_real_ip_from 0.0.0.0/0; real_ip_header X-Forwarded-For;
high
⌄
alias_traversal
location /files → alias /var/www/uploads (location без завершающего /)
Проверка
Проверка path traversal через alias
Решение
Добавьте завершающий / как в location, так и в alias: location /files/ { alias /data/files/; }
Фрагмент
demo.conf
return 302 https://example.com"var">$request_uri; add_header X-Custom "var">$http_referer; } # --- alias traversal --- location /files { alias /var/www/uploads; } # --- Конфликтующие location --- location /static {
high
⌄
alias_traversal
location /static → alias /var/www/assets/ (location без завершающего /)
Проверка
Проверка path traversal через alias
Решение
Добавьте завершающий / как в location, так и в alias: location /files/ { alias /data/files/; }
Фрагмент
demo.conf
location /files { alias /var/www/uploads; } # --- Конфликтующие location --- location /static { root /var/www; } location /static { alias /var/www/assets/; }
high
⌄
dotfile_exposed
server example.com www.example.com: нет блокировки dotfiles (/.env, /.git, /.htpasswd и др.)
Проверка
Проверка блокировки dotfiles (/.env, /.git и др.)
Решение
Добавьте: location ~ /\.(?!well-known) { deny all; } для блокировки /.env, /.git и др.
Фрагмент
demo.conf
# ========================================= # Сервер без default_server, без HTTPS redirect # ========================================= server { listen 80; server_name example.com www.example.com; # --- autoindex включён --- autoindex on; # --- .git открыт ---
high
⌄
dotfile_exposed
server secure.example.com: нет блокировки dotfiles (/.env, /.git, /.htpasswd и др.)
Проверка
Проверка блокировки dotfiles (/.env, /.git и др.)
Решение
Добавьте: location ~ /\.(?!well-known) { deny all; } для блокировки /.env, /.git и др.
Фрагмент
demo.conf
# --- autoindex включён --- autoindex on; # --- .git открыт --- # (нет блокировки location ~ /\.git) # --- dotfiles открыты (.env, .htpasswd) --- # (нет location ~ /\.) # --- backup-файлы открыты ---
high
⌄
dotfile_exposed
server example.com: нет блокировки dotfiles (/.env, /.git, /.htpasswd и др.)
Проверка
Проверка блокировки dotfiles (/.env, /.git и др.)
Решение
Добавьте: location ~ /\.(?!well-known) { deny all; } для блокировки /.env, /.git и др.
Фрагмент
demo.conf
# --- autoindex включён --- autoindex on; # --- .git открыт --- # (нет блокировки location ~ /\.git) # --- dotfiles открыты (.env, .htpasswd) --- # (нет location ~ /\.) # --- backup-файлы открыты ---
high
⌄
backup_files_exposed
Нет блокировки backup-файлов (.bak, .sql, .tar, .swp и др.) — добавьте: location ~* \.(bak|sql|tar|gz|swp|old)$ { deny all; }
Проверка
Проверка блокировки backup-файлов (.bak, .sql, .tar и др.)
Решение
Добавьте: location ~* \.(bak|sql|tar|gz|swp|old|orig|dump)$ { deny all; }
Фрагмент
demo.conf
# --- autoindex включён --- autoindex on; # --- .git открыт --- # (нет блокировки location ~ /\.git) # --- dotfiles открыты (.env, .htpasswd) --- # (нет location ~ /\.) # --- backup-файлы открыты ---
high
⌄
real_ip_from_any
set_real_ip_from 0.0.0.0/0 — доверяет всем IP, возможна подделка
Проверка
Проверка set_real_ip_from 0.0.0.0/0 (подделка IP)
Решение
Укажите конкретные IP/сети доверенных прокси вместо 0.0.0.0/0.
Фрагмент
demo.conf
# --- Внешний резолвер --- resolver 8.8.8.8; # --- set_real_ip_from любой --- set_real_ip_from 0.0.0.0/0; real_ip_header X-Forwarded-For; # ========================================= # Сервер без default_server, без HTTPS redirect # =========================================
high
⌄
php_fastcgi_unsafe
location ~ \.php$: fastcgi_pass без try_files $uri =404 — возможен file upload bypass (file.php.jpg)
Проверка
Проверка PHP FastCGI без try_files (file upload bypass)
Решение
Добавьте try_files $uri =404; перед fastcgi_pass для блокировки file upload bypass.
Фрагмент
demo.conf
location /nginx_status { stub_status; # нет allow/deny } # --- PHP FastCGI без try_files --- location ~ \.php$ { fastcgi_pass unix:/run/php/php-fpm.sock; fastcgi_param SCRIPT_FILENAME "var">$document_root"var">$fastcgi_script_name; include fastcgi_params; }
medium
⌄
location_conflict
server: None location: /static ↔ /static
Проверка
Проверка конфликтов location
Решение
Возможное пересечение location. Это не всегда ошибка: порядок и типы location могут быть корректны. Проверьте, что порядок и типы location соответствуют вашим ожиданиям. Если всё ок — игнорируйте предупреждение.
Фрагмент
demo.conf
location /files { alias /var/www/uploads; } # --- Конфликтующие location --- location /static { root /var/www; } location /static { alias /var/www/assets/; }
medium
⌄
no_limit_req_conn
server без limit_req/limit_conn в блоке 'None'
Проверка
Проверка наличия лимитов запросов/соединений
Решение
Добавьте limit_req/limit_conn для защиты от DDoS.
Фрагмент
demo.conf
# --- set_real_ip_from любой --- set_real_ip_from 0.0.0.0/0; real_ip_header X-Forwarded-For; # ========================================= # Сервер без default_server, без HTTPS redirect # ========================================= server { listen 80; server_name example.com www.example.com;
medium
⌄
autoindex_on
autoindex on в блоке server
Проверка
Проверка autoindex on
Решение
Отключите autoindex, если не требуется публикация файлов.
Фрагмент
demo.conf
# ========================================= server { listen 80; server_name example.com www.example.com; # --- autoindex включён --- autoindex on; # --- .git открыт --- # (нет блокировки location ~ /\.git)
medium
⌄
proxy_pass_no_scheme
proxy_pass без схемы: backend:3000
Проверка
Проверка proxy_pass на отсутствие схемы
Решение
Добавьте http:// или https:// в proxy_pass.
Фрагмент
demo.conf
# --- Дублирующиеся директивы --- root /var/www/html; root /var/www/site; # --- proxy_pass без схемы --- location / { proxy_pass backend:3000; proxy_set_header Host "var">$http_host; # host_spoofing }
medium
⌄
fastcgi_ip_disclosure
Блок с fastcgi_pass может раскрывать информацию: 'location ~ \.php$'
Проверка
Проверка раскрытия информации через FastCGI
Решение
Добавьте 'fastcgi_hide_header X-Powered-By;' и/или 'fastcgi_hide_header Location;' в блоки с fastcgi_pass для предотвращения раскрытия информации.
Фрагмент
demo.conf
# нет allow/deny } # --- PHP FastCGI без try_files --- location ~ \.php$ { fastcgi_pass unix:/run/php/php-fpm.sock; fastcgi_param SCRIPT_FILENAME "var">$document_root"var">$fastcgi_script_name; include fastcgi_params; } # --- if внутри location ---
medium
⌄
if_block
директива if внутри блока location
Проверка
Проверка использования if в location
Решение
Избегайте if внутри location, используйте map/try_files.
Фрагмент
demo.conf
fastcgi_pass unix:/run/php/php-fpm.sock; fastcgi_param SCRIPT_FILENAME "var">$document_root"var">$fastcgi_script_name; include fastcgi_params; } # --- if внутри location --- location /old { if ("var">$request_uri ~* "^/old/(.*)$") { return 301 /new/"var">$1; } }
medium
⌄
if_block
директива if внутри блока location
Проверка
Проверка использования if в location
Решение
Избегайте if внутри location, используйте map/try_files.
Фрагмент
demo.conf
fastcgi_pass unix:/run/php/php-fpm.sock; fastcgi_param SCRIPT_FILENAME "var">$document_root"var">$fastcgi_script_name; include fastcgi_params; } # --- if внутри location --- location /old { if ("var">$request_uri ~* "^/old/(.*)$") { return 301 /new/"var">$1; } }
medium
⌄
no_limit_req_conn
server без limit_req/limit_conn в блоке 'None'
Проверка
Проверка наличия лимитов запросов/соединений
Решение
Добавьте limit_req/limit_conn для защиты от DDoS.
Фрагмент
demo.conf
# --- set_real_ip_from любой --- set_real_ip_from 0.0.0.0/0; real_ip_header X-Forwarded-For; # ========================================= # Сервер без default_server, без HTTPS redirect # ========================================= server { listen 80; server_name example.com www.example.com;
medium
⌄
missing_ssl_stapling
Отсутствует 'ssl_stapling on' в SSL server-блоке ''
Проверка
Проверка OCSP Stapling
Решение
Включите OCSP Stapling (ssl_stapling on) для улучшения производительности и приватности TLS.
Фрагмент
demo.conf
server_name secure.example.com; ssl_certificate /etc/ssl/certs/example.com.pem; ssl_certificate_key /etc/ssl/private/example.com.key; # --- Нет ssl_dhparam --- # --- Нет ssl_stapling --- # --- Нет ssl_trusted_certificate --- # --- Нет limit_req/limit_conn --- location / {
medium
⌄
no_limit_req_conn
server без limit_req/limit_conn в блоке 'None'
Проверка
Проверка наличия лимитов запросов/соединений
Решение
Добавьте limit_req/limit_conn для защиты от DDoS.
Фрагмент
demo.conf
# --- set_real_ip_from любой --- set_real_ip_from 0.0.0.0/0; real_ip_header X-Forwarded-For; # ========================================= # Сервер без default_server, без HTTPS redirect # ========================================= server { listen 80; server_name example.com www.example.com;
medium
⌄
missing_security_header
отсутствует security header: Strict-Transport-Security
Проверка
Проверка наличия заголовков безопасности
Решение
Добавьте security-заголовок.
Фрагмент
demo.conf
# (нет location ~ /\.) # --- backup-файлы открыты --- # (нет location ~* \.(bak|sql|tar|gz|swp)) # --- Нет security-заголовков --- # (нет X-Frame-Options, X-Content-Type-Options и т.д.) # --- Дублирующиеся директивы --- root /var/www/html; root /var/www/site;
medium
⌄
missing_security_header
отсутствует security header: Referrer-Policy
Проверка
Проверка наличия заголовков безопасности
Решение
Добавьте security-заголовок.
Фрагмент
demo.conf
# (нет location ~ /\.) # --- backup-файлы открыты --- # (нет location ~* \.(bak|sql|tar|gz|swp)) # --- Нет security-заголовков --- # (нет X-Frame-Options, X-Content-Type-Options и т.д.) # --- Дублирующиеся директивы --- root /var/www/html; root /var/www/site;
medium
⌄
missing_security_header
отсутствует security header: Content-Security-Policy
Проверка
Проверка наличия заголовков безопасности
Решение
Добавьте security-заголовок.
Фрагмент
demo.conf
# (нет location ~ /\.) # --- backup-файлы открыты --- # (нет location ~* \.(bak|sql|tar|gz|swp)) # --- Нет security-заголовков --- # (нет X-Frame-Options, X-Content-Type-Options и т.д.) # --- Дублирующиеся директивы --- root /var/www/html; root /var/www/site;
medium
⌄
add_header_redefinition
location /api/ — теряет security-заголовки: x-content-type-options, x-frame-options
Проверка
Проверка сброса security-заголовков в дочерних блоках
Решение
Повторите нужные заголовки в дочернем блоке или используйте add_header_inherit merge (nginx 1.29.3+).
Фрагмент
demo.conf
proxy_pass backend:3000; proxy_set_header Host "var">$http_host; # host_spoofing } # --- SSRF через переменную в proxy_pass --- location /api/ { proxy_pass http://"var">$arg_target; } # --- HTTP Response Splitting --- location /redirect {
medium
⌄
default_server_flag
listen *:80 — 2 server-блока без default_server
Проверка
Проверка отсутствия default_server
Решение
Добавьте default_server к одному из server-блоков на этом адресе:порту.
Фрагмент
demo.conf
# --- set_real_ip_from любой --- set_real_ip_from 0.0.0.0/0; real_ip_header X-Forwarded-For; # ========================================= # Сервер без default_server, без HTTPS redirect # ========================================= server { listen 80; server_name example.com www.example.com;
medium
⌄
status_page_exposed
stub_status в блоке location /nginx_status — нет allow/deny all
Проверка
Проверка открытого stub_status
Решение
Ограничьте доступ к stub_status: добавьте allow 127.0.0.1; deny all;
Фрагмент
demo.conf
# --- metrics открыты --- location /metrics { proxy_pass http://prometheus:9090; } location /nginx_status { stub_status; # нет allow/deny } # --- PHP FastCGI без try_files ---
medium
⌄
metrics_exposed
location /metrics доступен без ограничений — добавьте allow/deny или auth_basic
Проверка
Проверка открытых metrics/debug endpoints
Решение
Ограничьте доступ к metrics/debug endpoint: добавьте allow 127.0.0.1; deny all; или auth_basic.
Фрагмент
demo.conf
location /admin-panel { proxy_pass http://backend:8080; } # --- metrics открыты --- location /metrics { proxy_pass http://prometheus:9090; } location /nginx_status { stub_status;
medium
⌄
metrics_exposed
location /nginx_status доступен без ограничений — добавьте allow/deny или auth_basic
Проверка
Проверка открытых metrics/debug endpoints
Решение
Ограничьте доступ к metrics/debug endpoint: добавьте allow 127.0.0.1; deny all; или auth_basic.
Фрагмент
demo.conf
location /admin-panel { proxy_pass http://backend:8080; } # --- metrics открыты --- location /metrics { proxy_pass http://prometheus:9090; } location /nginx_status { stub_status;
medium
⌄
missing_https_redirect
server example.com: listen 80 без redirect на HTTPS — возможен downgrade и перехват cookie
Проверка
Проверка отсутствия HTTPS redirect для HTTP
Решение
Добавьте return 301 https://$host$request_uri; в server { listen 80; }
Фрагмент
demo.conf
# --- set_real_ip_from любой --- set_real_ip_from 0.0.0.0/0; real_ip_header X-Forwarded-For; # ========================================= # Сервер без default_server, без HTTPS redirect # ========================================= server { listen 80; server_name example.com www.example.com;
medium
⌄
missing_client_max_body
client_max_body_size не задан — по умолчанию 1MB, возможен DoS или отказ в загрузке файлов
Проверка
Проверка отсутствия client_max_body_size
Решение
Явно задайте client_max_body_size в http-блоке: client_max_body_size 10m;
Фрагмент
demo.conf
events { worker_connections 128;}http { # --- Нет client_max_body_size --- # --- Устаревшие SSL-протоколы --- ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_ciphers DES-CBC3-SHA:RC4-SHA:AES128-SHA;
low
⌄
empty_block
location /empty
Проверка
Проверка пустых блоков
Решение
Удалите или заполните пустой блок.
Фрагмент
demo.conf
return 301 /new/"var">$1; } } # --- Пустой блок --- location /empty { } # --- rewrite без флага --- rewrite ^/blog/(.*)$ /articles/"var">$1;
low
⌄
server_tokens_not_hidden
Версия Server не скрыта/изменена в блоке 'http '
Проверка
Проверка скрытия версии Server
Решение
Скройте или измените заголовок Server (server_tokens off; или server_tokens build;) для уменьшения поверхности атаки.
Фрагмент
demo.conf
# --- set_real_ip_from любой --- set_real_ip_from 0.0.0.0/0; real_ip_header X-Forwarded-For; # ========================================= # Сервер без default_server, без HTTPS redirect # ========================================= server { listen 80; server_name example.com www.example.com;
low
⌄
listen_443_no_http2
listen 443 без http2: 443
Проверка
Проверка listen 443 без http2
Решение
Добавьте http2 к listen 443 для производительности.
Фрагмент
demo.conf
# ========================================= # SSL-сервер с проблемами # ========================================= server { listen 443; # нет ssl server_name secure.example.com; ssl_certificate /etc/ssl/certs/example.com.pem; ssl_certificate_key /etc/ssl/private/example.com.key; # --- Нет ssl_dhparam ---
low
⌄
rewrite_no_flag
^/blog/(.*)$ /articles/$1
Проверка
Проверка rewrite-правил без флагов
Решение
Добавьте last/break/redirect/permanent к rewrite.
Фрагмент
demo.conf
# --- Пустой блок --- location /empty { } # --- rewrite без флага --- rewrite ^/blog/(.*)$ /articles/"var">$1; # --- rewrite цикл --- rewrite ^/loop/(.*)$ /loop/"var">$1 last; # --- Переменная в root ---
low
⌄
dead_location
server: None location: /empty
Проверка
Проверка 'мертвых' location-ов
Решение
Удалите неиспользуемый location или используйте его.
Фрагмент
demo.conf
return 301 /new/"var">$1; } } # --- Пустой блок --- location /empty { } # --- rewrite без флага --- rewrite ^/blog/(.*)$ /articles/"var">$1;
Ничего не найдено
Пройденные проверки
Проверка дублирующихся директив
Проверка наличия SSL-директив
Проверка верификации OCSP Stapling
Проверка доверенного сертификата для OCSP
Проверка устаревших директив
Проверка слишком малых лимитов
Проверка слишком больших лимитов
Проверка неиспользуемых переменных
Проверка циклических rewrite-правил
Проверка конфликтов rewrite-правил
Проверка устаревшего DNS-кеша в proxy_pass
Проверка merge_slashes on
Проверка error_log off
Проверка отсутствия worker_processes
Проверка worker_rlimit_nofile vs worker_connections
Проверка admin-панелей без аутентификации