Nginx

Слышал как-то об инструменте для тестирования конфигураций веб-сервера nginx на наличие уязвимостей, но не обратил на него внимания. Сейчас узнал, что этот инструмент имеет в репозитории хорошо описанные сценарии эксплуатации искомых уязвимостей и неплохую Вики: https://github.com/yandex/gixy

https://github.com/wallarm/awesome-nginx-security

Ошибки конфигурации

Дефолтный конфиг

Пусть есть дефолтный конфиг nginx. Разработчик копирует его, называет example.com и настраивает на нем что-то (например, php). А default не удаляет. При обращении к example.com/index.php - отрабатывает страничка.

При входе на любой не существующий виртуальный домен на сервере (меняем host), выведется дефолтная страничка (ее обработает дефолтная конфигурация сервера) - "Welcome to Nginx".

Фишечка: можем сделать следующий запрос и увидеть сорцы:

GET /example.com/index.php
Host: localhost

Один upstream

Иногда пускают через один upstream поток на два сервиса (например, два разных сервачка).

Допустим, есть два хоста: a.example.com и b.example.com. На a-хосте вход по сертам, на b-хосте - нет. Тогда, иногда, может получится такая штука:

curl -H "Host: a.example.com" http://b.example.com -v -k

И мы попадаем на a.example.com без авторизации.

Missing root location

В этом конфиге не описано как обрабатывать location /, а только location /hello.txt. При обращении например к /nginx.conf будет прочтен файл /etc/nginx/nginx.conf.

Off-by-Slash

В этом конфиге location /api не закрыто слешем. Как происходиит обработка такого запроса:

 Сначала nginx нормализует URL (например: http://apiserver/api/user/../user -> http://apiserver/api/user). Затем ищет префикс /api и все, что после него, подставляет в proxy_pass:

Затем этот URL нормализуется.

Ну а если мы запросим вот такой адрес?)

Ответ: он уйдет на http://apiserver/server-status.

Небезопасное использование переменных nginx

SCRIPT_NAME

Здесь основная проблема в том, что PHP интерпретатору будет отправлен любой URL (если он оканчивается на php), даже если самого скрипта нет.

Например: если обратиться /v1/exploit_php.jpg/notexist.php, то если не выставлены определенные флаги, fastcgi интерпретатор отбросит notexist.php и попытается обратиться к exploit_php.jpg и проинтерпретировать его как php скрипт.

Подробнее и больше примеров: https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/#passing-uncontrolled-requests-to-php

Обработка сырых данных от бэкенд сервера

Nginx в моде proxy_pass может скрывать ошибки и заголовки, приходящие с бэкенд-сервера. Это очень удобно. Nginx автоматом подсунет дефолтную страничку на ошибки. Но что, если nginx не поймет ответ сервера?

Если клиент отправит некорректный http запрос, то он будет переслан бэкенд-серверу как есть; сервер вернет raw ответ и Nginx его не сможет обработать и вернет его клиенту как есть. ТТаким образом можно увидеть какие-то необычные заголовки, данные и тп

Например:

Бэкенд приложение:

Nginx конфиг:

proxy_intercept_errors вернет страницу ошибки error_page, если код ответа сервера > 300

Если отправить нормальный GET запрос, то Nginx вернет:

Но, если отправить некорректный запрос, такой как:

То Nginx вернет следующий ответ:

Path Traversal

Если директива в конфиге Nginx merge_slashes включена (on), то Nginx будет убирать лишние слэши, например /// -> /, ///../../ -> /../../.

Если директива выключена, то возможны случаи, когда:

Подробнее: https://medium.com/appsflyer/nginx-may-be-protecting-your-applications-from-traversal-attacks-without-you-even-knowing-b08f882fd43d

Last updated

Was this helpful?