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 значение вида «http://example.com/#;nнастройки» и подставить свои настройки в файл конфигурации.
Для выполнения произвольного кода в процессе проверки конфигурации командой «nginx -t» исследователи воспользовались тем, что помимо проверки синтаксиса nginx загружает библиотеки с модулями и открывает файлы, упомянутые в конфигурации, для оценки их доступности. Среди прочего, при обработке директивы ssl_engine производится загрузка указанной в директиве разделяемой библиотеки для SSL-движка.
Для загрузки своей библиотеки на сервер Kubernetes исследователи воспользовались (CVE-2025-1974) тем, что при обработке больших запросов nginx сохраняет тело запроса во временном файле, который сразу удаляется, но в файловой системе «/proc» для этого файла остаётся открытый файловый дескриптор. Таким образом, можно одновременно отправить запросы для сохранения временного файла и инициирования проверки конфигурации, в которой в директиве «ssl_engine» указан путь к дескриптору в файловой системе «/proc».
Для того, чтобы файловый дескриптор длительное время оставался доступен значение «Content-Length» в запросе можно указать заведомо большим, чем фактически переданные данные (сервер будет ждать приёма оставшихся данных). Дополнительной сложностью является необходимость угадать PID процесса и номер файлового дескриптора, связанного с загруженной разделяемой библиотекой, но так как в контейнере обычно используется минимальное число запущенных процессов, нужные значения угадываются путём перебора в несколько попыток. В случае успеха и загрузки подставленной разделяемой библиотеки, атакующий может получить доступ к хранимым внутри pod-окружения параметрам, достаточным для управления всем кластером.
Для проверки использования уязвимого ingress-nginx можно выполнить команду:
kubectl get pods --all-namespaces --selector app.kubernetes.io/name=ingress-nginx
Источник: http://www.opennet.ru/opennews/art.shtml?num=62946