/ security-audit / analyze
Wiki
/etc/nginx/demo.conf
34 critical 21 medium 5 low 16 passed
ssl_protocols_weak high
ssl_protocols содержит устаревшие протоколы: TLSv1 TLSv1.1 TLSv1.2
Check
Проверка устаревших SSL-протоколов
Solution
Отключите устаревшие протоколы TLS.
Fragment 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;
ssl_ciphers_weak high
ssl_ciphers содержит слабые шифры: DES-CBC3-SHA:RC4-SHA:AES128-SHA
Check
Проверка слабых SSL-шифров
Solution
Используйте современные шифры.
Fragment 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 отключён ---
git_exposed high
Возможен доступ к .git в server-блоке 'example.com www.example.com'
Check
Проверка доступа к .git
Solution
Добавьте 'location ~ /\.git/ { deny all; }' для блокировки доступа к репозиторию.
Fragment demo.conf
        server_name example.com www.example.com;        # --- autoindex включён ---        autoindex on;        # --- .git открыт ---        # (нет блокировки location ~ /\.git)        # --- dotfiles открыты (.env, .htpasswd) ---        # (нет location ~ /\.)
proxy_ip_disclosure high
Блок с proxy_pass не защищен от раскрытия внутренних IP: 'location /'
Check
Проверка раскрытия внутренних IP-адресов
Solution
Добавьте 'proxy_redirect off;' или 'proxy_redirect default;' в блоки с proxy_pass для предотвращения раскрытия внутренних IP-адресов.
Fragment 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        }
proxy_ip_disclosure high
Блок с proxy_pass не защищен от раскрытия внутренних IP: 'location /api/'
Check
Проверка раскрытия внутренних IP-адресов
Solution
Добавьте 'proxy_redirect off;' или 'proxy_redirect default;' в блоки с proxy_pass для предотвращения раскрытия внутренних IP-адресов.
Fragment 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        }
proxy_ip_disclosure high
Блок с proxy_pass не защищен от раскрытия внутренних IP: 'location /internal'
Check
Проверка раскрытия внутренних IP-адресов
Solution
Добавьте 'proxy_redirect off;' или 'proxy_redirect default;' в блоки с proxy_pass для предотвращения раскрытия внутренних IP-адресов.
Fragment 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        }
proxy_ip_disclosure high
Блок с proxy_pass не защищен от раскрытия внутренних IP: 'location /admin-panel'
Check
Проверка раскрытия внутренних IP-адресов
Solution
Добавьте 'proxy_redirect off;' или 'proxy_redirect default;' в блоки с proxy_pass для предотвращения раскрытия внутренних IP-адресов.
Fragment 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        }
proxy_ip_disclosure high
Блок с proxy_pass не защищен от раскрытия внутренних IP: 'location /metrics'
Check
Проверка раскрытия внутренних IP-адресов
Solution
Добавьте 'proxy_redirect off;' или 'proxy_redirect default;' в блоки с proxy_pass для предотвращения раскрытия внутренних IP-адресов.
Fragment 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        }
root_alias_with_variable high
Директива 'root' использует переменную: /var/www/$host
Check
Проверка 'root'/'alias' на использование переменных
Solution
Использование переменных в директивах 'root' или 'alias' может привести к уязвимостям обхода каталога (Path Traversal).
Fragment 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;
git_exposed high
Возможен доступ к .git в server-блоке 'secure.example.com'
Check
Проверка доступа к .git
Solution
Добавьте 'location ~ /\.git/ { deny all; }' для блокировки доступа к репозиторию.
Fragment demo.conf
        server_name example.com www.example.com;        # --- autoindex включён ---        autoindex on;        # --- .git открыт ---        # (нет блокировки location ~ /\.git)        # --- dotfiles открыты (.env, .htpasswd) ---        # (нет location ~ /\.)
missing_ssl_dhparam high
Отсутствует 'ssl_dhparam' в SSL server-блоке ''
Check
Проверка наличия ssl_dhparam
Solution
Укажите сильные параметры Диффи-Хеллмана (ssl_dhparam) для защиты от атак.
Fragment 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 ---
listen_443_no_ssl high
listen без ssl: 443
Check
Проверка listen 443 без ssl
Solution
Добавьте ssl к listen 443.
Fragment 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 ---
proxy_ip_disclosure high
Блок с proxy_pass не защищен от раскрытия внутренних IP: 'location /'
Check
Проверка раскрытия внутренних IP-адресов
Solution
Добавьте 'proxy_redirect off;' или 'proxy_redirect default;' в блоки с proxy_pass для предотвращения раскрытия внутренних IP-адресов.
Fragment 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        }
proxy_ip_disclosure high
Блок с proxy_pass не защищен от раскрытия внутренних IP: 'location /api/'
Check
Проверка раскрытия внутренних IP-адресов
Solution
Добавьте 'proxy_redirect off;' или 'proxy_redirect default;' в блоки с proxy_pass для предотвращения раскрытия внутренних IP-адресов.
Fragment 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        }
git_exposed high
Возможен доступ к .git в server-блоке 'example.com'
Check
Проверка доступа к .git
Solution
Добавьте 'location ~ /\.git/ { deny all; }' для блокировки доступа к репозиторию.
Fragment demo.conf
        server_name example.com www.example.com;        # --- autoindex включён ---        autoindex on;        # --- .git открыт ---        # (нет блокировки location ~ /\.git)        # --- dotfiles открыты (.env, .htpasswd) ---        # (нет location ~ /\.)
listen_servername_conflict high
server1: None server2: None listen: 80 server_name: example.com
Check
Проверка конфликтов listen/server_name
Solution
Измените listen/server_name для устранения конфликта.
Fragment 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;            }
ssrf high
http://$arg_target (переменная $arg_target в хосте/схеме)
Check
Проверка SSRF через proxy_pass
Solution
Замените переменную в host/scheme на фиксированное значение или используйте map с белым списком.
Fragment 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;
http_splitting high
proxy_set_header … $http_host (может содержать \n/\r)
Check
Проверка HTTP Response Splitting
Solution
Не используйте $request_uri/$arg_*/$http_* в заголовках и редиректах напрямую — применяйте $uri или sanitize-переменную.
Fragment 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;
http_splitting high
proxy_pass … $arg_target (может содержать \n/\r)
Check
Проверка HTTP Response Splitting
Solution
Не используйте $request_uri/$arg_*/$http_* в заголовках и редиректах напрямую — применяйте $uri или sanitize-переменную.
Fragment 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;
http_splitting high
return … $request_uri (может содержать \n/\r)
Check
Проверка HTTP Response Splitting
Solution
Не используйте $request_uri/$arg_*/$http_* в заголовках и редиректах напрямую — применяйте $uri или sanitize-переменную.
Fragment 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 {
http_splitting high
add_header … $http_referer (может содержать \n/\r)
Check
Проверка HTTP Response Splitting
Solution
Не используйте $request_uri/$arg_*/$http_* в заголовках и редиректах напрямую — применяйте $uri или sanitize-переменную.
Fragment 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;
host_spoofing high
proxy_set_header Host $http_host
Check
Проверка подделки Host-заголовка
Solution
Замените $http_host на $host в proxy_set_header Host.
Fragment 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;
return_bypasses_allow_deny high
location /admin
Check
Проверка обхода allow/deny через return
Solution
Перенесите return в named location или используйте try_files; allow/deny не защищают от return в том же блоке.
Fragment 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";        }
allow_without_deny high
location /internal — нет deny all
Check
Проверка allow без deny all
Solution
Добавьте deny all; после директив allow.
Fragment 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;
valid_referers_none high
none server_names
Check
Проверка valid_referers none
Solution
Уберите none из valid_referers или используйте другой механизм защиты.
Fragment 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;        }
resolver_external high
8.8.8.8
Check
Проверка внешнего DNS resolver
Solution
Используйте локальный resolver (127.0.0.1) вместо внешних DNS-серверов.
Fragment 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;
alias_traversal high
location /files → alias /var/www/uploads (location без завершающего /)
Check
Проверка path traversal через alias
Solution
Добавьте завершающий / как в location, так и в alias: location /files/ { alias /data/files/; }
Fragment 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 {
alias_traversal high
location /static → alias /var/www/assets/ (location без завершающего /)
Check
Проверка path traversal через alias
Solution
Добавьте завершающий / как в location, так и в alias: location /files/ { alias /data/files/; }
Fragment demo.conf
        location /files {            alias /var/www/uploads;        }        # --- Конфликтующие location ---        location /static {            root /var/www;        }        location /static {            alias /var/www/assets/;        }
dotfile_exposed high
server example.com www.example.com: нет блокировки dotfiles (/.env, /.git, /.htpasswd и др.)
Check
Проверка блокировки dotfiles (/.env, /.git и др.)
Solution
Добавьте: location ~ /\.(?!well-known) { deny all; } для блокировки /.env, /.git и др.
Fragment demo.conf
    # =========================================    # Сервер без default_server, без HTTPS redirect    # =========================================    server {        listen 80;        server_name example.com www.example.com;        # --- autoindex включён ---        autoindex on;        # --- .git открыт ---
dotfile_exposed high
server secure.example.com: нет блокировки dotfiles (/.env, /.git, /.htpasswd и др.)
Check
Проверка блокировки dotfiles (/.env, /.git и др.)
Solution
Добавьте: location ~ /\.(?!well-known) { deny all; } для блокировки /.env, /.git и др.
Fragment demo.conf
        # --- autoindex включён ---        autoindex on;        # --- .git открыт ---        # (нет блокировки location ~ /\.git)        # --- dotfiles открыты (.env, .htpasswd) ---        # (нет location ~ /\.)        # --- backup-файлы открыты ---
dotfile_exposed high
server example.com: нет блокировки dotfiles (/.env, /.git, /.htpasswd и др.)
Check
Проверка блокировки dotfiles (/.env, /.git и др.)
Solution
Добавьте: location ~ /\.(?!well-known) { deny all; } для блокировки /.env, /.git и др.
Fragment demo.conf
        # --- autoindex включён ---        autoindex on;        # --- .git открыт ---        # (нет блокировки location ~ /\.git)        # --- dotfiles открыты (.env, .htpasswd) ---        # (нет location ~ /\.)        # --- backup-файлы открыты ---
backup_files_exposed high
Нет блокировки backup-файлов (.bak, .sql, .tar, .swp и др.) — добавьте: location ~* \.(bak|sql|tar|gz|swp|old)$ { deny all; }
Check
Проверка блокировки backup-файлов (.bak, .sql, .tar и др.)
Solution
Добавьте: location ~* \.(bak|sql|tar|gz|swp|old|orig|dump)$ { deny all; }
Fragment demo.conf
        # --- autoindex включён ---        autoindex on;        # --- .git открыт ---        # (нет блокировки location ~ /\.git)        # --- dotfiles открыты (.env, .htpasswd) ---        # (нет location ~ /\.)        # --- backup-файлы открыты ---
real_ip_from_any high
set_real_ip_from 0.0.0.0/0 — доверяет всем IP, возможна подделка
Check
Проверка set_real_ip_from 0.0.0.0/0 (подделка IP)
Solution
Укажите конкретные IP/сети доверенных прокси вместо 0.0.0.0/0.
Fragment 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    # =========================================
php_fastcgi_unsafe high
location ~ \.php$: fastcgi_pass без try_files $uri =404 — возможен file upload bypass (file.php.jpg)
Check
Проверка PHP FastCGI без try_files (file upload bypass)
Solution
Добавьте try_files $uri =404; перед fastcgi_pass для блокировки file upload bypass.
Fragment 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;        }
location_conflict medium
server: None location: /static ↔ /static
Check
Проверка конфликтов location
Solution
Возможное пересечение location. Это не всегда ошибка: порядок и типы location могут быть корректны. Проверьте, что порядок и типы location соответствуют вашим ожиданиям. Если всё ок — игнорируйте предупреждение.
Fragment demo.conf
        location /files {            alias /var/www/uploads;        }        # --- Конфликтующие location ---        location /static {            root /var/www;        }        location /static {            alias /var/www/assets/;        }
no_limit_req_conn medium
server без limit_req/limit_conn в блоке 'None'
Check
Проверка наличия лимитов запросов/соединений
Solution
Добавьте limit_req/limit_conn для защиты от DDoS.
Fragment 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;
autoindex_on medium
autoindex on в блоке server
Check
Проверка autoindex on
Solution
Отключите autoindex, если не требуется публикация файлов.
Fragment demo.conf
    # =========================================    server {        listen 80;        server_name example.com www.example.com;        # --- autoindex включён ---        autoindex on;        # --- .git открыт ---        # (нет блокировки location ~ /\.git)
proxy_pass_no_scheme medium
proxy_pass без схемы: backend:3000
Check
Проверка proxy_pass на отсутствие схемы
Solution
Добавьте http:// или https:// в proxy_pass.
Fragment 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        }
fastcgi_ip_disclosure medium
Блок с fastcgi_pass может раскрывать информацию: 'location ~ \.php$'
Check
Проверка раскрытия информации через FastCGI
Solution
Добавьте 'fastcgi_hide_header X-Powered-By;' и/или 'fastcgi_hide_header Location;' в блоки с fastcgi_pass для предотвращения раскрытия информации.
Fragment 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 ---
if_block medium
директива if внутри блока location
Check
Проверка использования if в location
Solution
Избегайте if внутри location, используйте map/try_files.
Fragment 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;            }        }
if_block medium
директива if внутри блока location
Check
Проверка использования if в location
Solution
Избегайте if внутри location, используйте map/try_files.
Fragment 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;            }        }
no_limit_req_conn medium
server без limit_req/limit_conn в блоке 'None'
Check
Проверка наличия лимитов запросов/соединений
Solution
Добавьте limit_req/limit_conn для защиты от DDoS.
Fragment 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;
missing_ssl_stapling medium
Отсутствует 'ssl_stapling on' в SSL server-блоке ''
Check
Проверка OCSP Stapling
Solution
Включите OCSP Stapling (ssl_stapling on) для улучшения производительности и приватности TLS.
Fragment 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 / {
ssl_session_tickets_enabled medium
ssl_session_tickets не отключены в SSL server-блоке 'secure.example.com'
Check
Проверка ssl_session_tickets off
Solution
Добавьте ssl_session_tickets off; — session tickets нарушают forward secrecy при компрометации ticket key.
Fragment 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;
no_limit_req_conn medium
server без limit_req/limit_conn в блоке 'None'
Check
Проверка наличия лимитов запросов/соединений
Solution
Добавьте limit_req/limit_conn для защиты от DDoS.
Fragment 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;
missing_security_header medium
отсутствует security header: Strict-Transport-Security
Check
Проверка наличия заголовков безопасности
Solution
Добавьте security-заголовок.
Fragment 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;
missing_security_header medium
отсутствует security header: Referrer-Policy
Check
Проверка наличия заголовков безопасности
Solution
Добавьте security-заголовок.
Fragment 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;
missing_security_header medium
отсутствует security header: Content-Security-Policy
Check
Проверка наличия заголовков безопасности
Solution
Добавьте security-заголовок.
Fragment 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;
add_header_redefinition medium
location /api/ — теряет security-заголовки: x-content-type-options, x-frame-options
Check
Проверка сброса security-заголовков в дочерних блоках
Solution
Повторите нужные заголовки в дочернем блоке или используйте add_header_inherit merge (nginx 1.29.3+).
Fragment 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 {
default_server_flag medium
listen *:80 — 2 server-блока без default_server
Check
Проверка отсутствия default_server
Solution
Добавьте default_server к одному из server-блоков на этом адресе:порту.
Fragment 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;
status_page_exposed medium
stub_status в блоке location /nginx_status — нет allow/deny all
Check
Проверка открытого stub_status
Solution
Ограничьте доступ к stub_status: добавьте allow 127.0.0.1; deny all;
Fragment demo.conf
        # --- metrics открыты ---        location /metrics {            proxy_pass http://prometheus:9090;        }        location /nginx_status {            stub_status;            # нет allow/deny        }        # --- PHP FastCGI без try_files ---
metrics_exposed medium
location /metrics доступен без ограничений — добавьте allow/deny или auth_basic
Check
Проверка открытых metrics/debug endpoints
Solution
Ограничьте доступ к metrics/debug endpoint: добавьте allow 127.0.0.1; deny all; или auth_basic.
Fragment demo.conf
        location /admin-panel {            proxy_pass http://backend:8080;        }        # --- metrics открыты ---        location /metrics {            proxy_pass http://prometheus:9090;        }        location /nginx_status {            stub_status;
metrics_exposed medium
location /nginx_status доступен без ограничений — добавьте allow/deny или auth_basic
Check
Проверка открытых metrics/debug endpoints
Solution
Ограничьте доступ к metrics/debug endpoint: добавьте allow 127.0.0.1; deny all; или auth_basic.
Fragment demo.conf
        location /admin-panel {            proxy_pass http://backend:8080;        }        # --- metrics открыты ---        location /metrics {            proxy_pass http://prometheus:9090;        }        location /nginx_status {            stub_status;
missing_https_redirect medium
server example.com: listen 80 без redirect на HTTPS — возможен downgrade и перехват cookie
Check
Проверка отсутствия HTTPS redirect для HTTP
Solution
Добавьте return 301 https://$host$request_uri; в server { listen 80; }
Fragment 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;
missing_client_max_body medium
client_max_body_size не задан — по умолчанию 1MB, возможен DoS или отказ в загрузке файлов
Check
Проверка отсутствия client_max_body_size
Solution
Явно задайте client_max_body_size в http-блоке: client_max_body_size 10m;
Fragment 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;
empty_block low
location /empty
Check
Проверка пустых блоков
Solution
Удалите или заполните пустой блок.
Fragment demo.conf
                return 301 /new/"var">$1;            }        }        # --- Пустой блок ---        location /empty {        }        # --- rewrite без флага ---        rewrite ^/blog/(.*)$ /articles/"var">$1;
server_tokens_not_hidden low
Версия Server не скрыта/изменена в блоке 'http '
Check
Проверка скрытия версии Server
Solution
Скройте или измените заголовок Server (server_tokens off; или server_tokens build;) для уменьшения поверхности атаки.
Fragment 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;
listen_443_no_http2 low
listen 443 без http2: 443
Check
Проверка listen 443 без http2
Solution
Добавьте http2 к listen 443 для производительности.
Fragment 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 ---
rewrite_no_flag low
^/blog/(.*)$ /articles/$1
Check
Проверка rewrite-правил без флагов
Solution
Добавьте last/break/redirect/permanent к rewrite.
Fragment demo.conf
        # --- Пустой блок ---        location /empty {        }        # --- rewrite без флага ---        rewrite ^/blog/(.*)$ /articles/"var">$1;        # --- rewrite цикл ---        rewrite ^/loop/(.*)$ /loop/"var">$1 last;        # --- Переменная в root ---
dead_location low
server: None location: /empty
Check
Проверка 'мертвых' location-ов
Solution
Удалите неиспользуемый location или используйте его.
Fragment demo.conf
                return 301 /new/"var">$1;            }        }        # --- Пустой блок ---        location /empty {        }        # --- rewrite без флага ---        rewrite ^/blog/(.*)$ /articles/"var">$1;
No issues match your search.
Check your config
Paste your nginx.conf — all the same checks will be applied.
Fixed config
Auto-fixed version of your config. Review all changes before applying.