Уязвимости в Ingress-nginx, позволяющие выполнить код и захватить управление кластерами Kubernetes

В развиваемом проектом Kubernetes ingress-контроллере ingress-nginx выявлены четыре уязвимости, позволяющие добиться выполнения своего кода на серверах облачных систем, использующих платформу Kubernete, и получить полный привилегированный доступ к кластеру Kubernete. Проблемам присвоен критический уровень опасности (9.8 из 10). Выявившие проблемы исследователи присвоили уязвимостям кодовое имя IngressNightmare и отметили, что уязвимости затрагивают около 43% облачных окружений. Уязвимости устранены в версиях ingress-nginx 1.11.5 и 1.12.1.

Ingress-контроллер выступает в роли шлюза и используется в Kubernetes для организации доступа из внешней сети к сервисам внутри кластера. Контроллер ingress-nginx является наиболее популярным и применяет сервер NGINX для проброса обращений к кластеру, маршрутизации внешних запросов и балансировки нагрузки. Проект Kubernetes предоставляет базовые ingress-контроллеры для AWS, GCE и nginx, последний из которых никак не связан с контроллером kubernetes-ingress, сопровождением которого занимается компания F5/NGINX (рассматриваемые уязвимости не затрагивают проекты, развиваемые разработчиками NGINX, упоминание nginx в названии ingress-nginx связано лишь с задействованием nginx в качестве прокси).

Уязвимости позволяют неаутентифицированному атакующему добиться выполнения своего кода в контексте контроллера ingress-nginx, при возможности отправки запроса к web-обработчику Admission. В ходе сканирования сети выявлено более 6500 уязвимых кластеров Kubernetes, использующих общедоступные уязвимые контроллеры с открытым для внешних запросов обработчиком Admission.

В конфигурации по умолчанию запущенный атакующим код может получить доступ к настройкам объекта Ingress, в которых, среди прочего, хранятся и учётные данные для обращения к серверам Kubernetes, что позволяет добиться привилегированного доступа ко всему кластеру. В качестве обходного пути защиты рекомендуется отключить в ingress-nginx функцию “Validating Admission Controller”.

Контроллер Admission запускается в отдельном pod-окружении и выполняет операцию проверки входящих ingress-объектов перед их развёртыванием. По умолчанию web-обработчик Admission принимает запросы без аутентификации из публичной сети. При выполнении проверки контроллер Admission создаёт конфигурацию для http-сервера nginx на основе содержимого полученного ingress-объекта и проверяет её корректность.

Выявленные уязвимости позволяют добиться подстановки своих настроек в nginx через отправку специально оформленного ingress-объекта напрямую в контроллер Admission. Исследователи обнаружили, что некоторые свойства проверочных запросов, выставленные в поле “.request.object.annotations”, напрямую подставляются в конфигурацию nginx. При этом сгенерированная конфигурация не применяется, а лишь тестируется путём запуска исполняемого файла “nginx” c опцией “-t”.

В частности, подстановка внешних данных в конфигурацию выполняется для параметров “mirror-target”, “mirror-host” (CVE-2025-1098), “auth-tls-match-cn” (CVE-2025-1097) и “auth-url” (CVE-2025-24514).
Например, в строке конфигурации “set $target {{ $externalAuth.URL }};” вместо “{{ $externalAuth.URL }}” подставляется URL, указанный в параметре “auth-url”. При этом корректность URL не проверяется. Соответственно, атакующий может передать в качестве URL значение вида “https://example.com/#;nнастройки” и подставить свои настройки в файл конфигурации.

Для выполнения произвольного кода в процессе проверки конфигурации командой “nginx -t” исследователи воспользовались тем, что помимо проверки синтаксиса nginx загружает библиотеки с модулями и открывает файлы, упомянутые в конфигурации, для оценки их доступности. Среди прочего, при обработке директивы ssl_engine производится загрузка указанной в директиве разделяемой библиотеки для SSL-движка.

Для загрузки своей библиотеки на сервер Kubernetes исследователи воспользовались (CVE-2025-1974) тем, что при обработке больших запросов nginx сохраняет тело запроса во временном файле, который сразу удаляется, но в файловой системе “/proc” для этого файла остаётся открытый файловый дескриптор. Таким образом, можно одновременно отправить запросы для сохранения временного файла и инициирования проверки конфигурации, в которой в директиве “ssl_engine” указан путь к дескриптору в файловой системе “/proc”.

Для того, чтобы файловый дескриптор длительное время оставался доступен значение “Content-Length” в запросе можно указать заведомо большим, чем фактически переданные данные (сервер будет ждать приёма оставшихся данных). Дополнительной сложностью является необходимость угадать PID процесса и номер файлового дескриптора, связанного с загруженной разделяемой библиотекой, но так как в контейнере обычно используется минимальное число запущенных процессов, нужные значения угадываются путём перебора в несколько попыток. В случае успеха и загрузки подставленной разделяемой библиотеки, атакующий может получить доступ к хранимым внутри pod-окружения параметрам, достаточным для управления всем кластером.



Для проверки использования уязвимого ingress-nginx можно выполнить команду:

Release. Ссылка here.