In March 2026 the Kubernetes Security Response Committee published two ingress-nginx advisories with the same shape. CVE-2026-3288 (9 March) lets the rewrite-target annotation inject configuration into nginx, and CVE-2026-4342 (19 March) does the same through a combination of annotations. Both are rated 8.8 and both can lead to code execution in the controller and disclosure of Secrets it can read. For CVE-2026-3288 the advisory names a stopgap before you upgrade: use admission control to block the annotation.
If you have never written an admission policy, this is a good first one, because the built-in ValidatingAdmissionPolicy needs no webhook server, no certificates and no extra pod.
What's affected
ingress-nginx, in these ranges per the advisories:
- CVE-2026-3288: versions below 1.13.8, below 1.14.4 and below 1.15.0.
- CVE-2026-4342: versions below 1.13.9, below 1.14.5 and below 1.15.1.
Upgrading to 1.13.9, 1.14.5 or 1.15.1 or later covers both. The advisories note that in the default installation the controller can read Secrets cluster-wide, which is why code execution in that pod is serious. If ingress-nginx is not installed, you are not affected. Both advisories were reported by outside researchers, Kai Aizen for CVE-2026-3288 and wooseokdotkim for CVE-2026-4342.
How to check if you're exposed
The advisory's own check for whether ingress-nginx runs in your cluster:
kubectl get pods --all-namespaces --selector app.kubernetes.io/name=ingress-nginx
Then read the image tag of the controller:
kubectl get pods -A -l app.kubernetes.io/name=ingress-nginx \
-o jsonpath='{range .items[*]}{.metadata.namespace}/{.metadata.name}: {.spec.containers[*].image}{"\n"}{end}'
Find existing Ingresses that already use the annotation:
kubectl get ingress -A -o json | jq -r '
.items[]
| select(.metadata.annotations // {} | has("nginx.ingress.kubernetes.io/rewrite-target"))
| "\(.metadata.namespace)/\(.metadata.name)"'
The advisories give one detection hint: suspicious data inside rules.http.paths.path of an Ingress could indicate an attempt. Dump the paths and read them with your own eyes.
What to do now
- Upgrade ingress-nginx to a fixed version using the project's upgrade guide linked from the advisory.
- While you plan the upgrade, add this policy. It follows the structure in the Kubernetes docs (stable since v1.30):
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: block-risky-ingress-annotations.example.com
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: ["networking.k8s.io"]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["ingresses"]
validations:
- expression: "!has(object.metadata.annotations) || !('nginx.ingress.kubernetes.io/rewrite-target' in object.metadata.annotations)"
message: "The rewrite-target annotation is blocked cluster-wide until ingress-nginx is upgraded."
- Bind it in audit mode first. The docs list Deny, Warn and Audit as validation actions, and Warn and Audit can be combined:
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: block-risky-ingress-annotations-binding.example.com
spec:
policyName: block-risky-ingress-annotations.example.com
validationActions: [Warn, Audit]
- Read the audit annotations for a day, fix the Ingresses that trip the rule, then change the binding to
[Deny]. - Test the deny path without creating anything. A server-side dry run goes through admission and returns the policy message:
kubectl apply --dry-run=server -f ingress.yaml
- Remove the policy once every controller is on a fixed version, or keep it and widen it to the other annotations you decide nobody should set.
The Kubernetes docs warn that admission policies are part of the control plane and should be deployed with great caution. A broken Fail policy on a core resource blocks real changes, which is why steps 3 and 4 come before Deny.
How this could have been avoided
- Admission control on annotations. The advisory lists it as the mitigation. A policy that rejects dangerous annotation keys turns a tenant's Ingress write into a rejected request.
- Fewer people allowed to create Ingress objects. The CVSS vector for both issues requires low privileges, meaning any identity that can write an Ingress. Restrict that verb with RBAC and give application teams a reviewed path.
- Limit what the controller can read. The advisories point out that the default install reads Secrets cluster-wide. Review the controller's RBAC and narrow it to the namespaces it serves.
- Egress limits on the controller pod. If code does run there, a default-deny egress policy limits where stolen data can go.
- A patch routine for cluster add-ons. Ingress controllers sit on the edge. Track them like your base images, with a version inventory and an owner.
Why it matters
Annotations look like metadata, but for an ingress controller they are input that becomes configuration. Any controller that renders text config from user-controlled fields has this risk. The Kubernetes CVE feed lists a long run of ingress-nginx entries for 2025 and 2026, and the pattern is consistent.
An in-process admission policy is cheap to add and easy to remove. Treat it as a standing guardrail for the next annotation bug, not as a one-off patch.
Try it yourself
On a test cluster, apply the policy with the Warn and Audit binding, then submit an Ingress that sets the rewrite-target annotation as a server-side dry run (step 5). Confirm you get a warning and not an error. Switch the binding to Deny and repeat. Then see how the same idea looks as a production gate.
Click through it at your own pace, or open it full screen.
Quick check
Why bind the policy with Warn and Audit before Deny?
It shows which existing and planned Ingresses would be rejected, so you can fix them before the policy starts blocking real changes.
What does the advisory for CVE-2026-3288 say you can do before upgrading?
Use admission control to block the use of the rewrite-target annotation.
Sources
- Kubernetes issue 137560: CVE-2026-3288 ingress-nginx rewrite-target nginx configuration injection
- Kubernetes issue 137893: CVE-2026-4342 ingress-nginx comment-based nginx configuration injection
- Kubernetes security announcement for CVE-2026-4342
- Kubernetes docs: Validating Admission Policy
- Kubernetes official CVE feed