← Back to Attack Research

A double quote in an ingress path: config injection to RCE in ingress-nginx

One quote character in a rewrite-target annotation breaks out of the nginx configuration the ingress-nginx controller generates and injects arbitrary directives. Because those directives can run code, the controller executes attacker input, and in a default install it can read every Secret in the cluster. Here is how CVE-2026-3288 works, why anyone who can create an Ingress can reach it, and what closes it.

One character does the damage: a double quote in a Kubernetes Ingress annotation. The ingress-nginx controller takes the value you place in a rewrite-target annotation and writes it into the nginx configuration it generates. If that value contains a ", it ends the string the controller intended and lets whatever follows be parsed as new nginx directives. Some directives can execute code. So a field that looks like routing metadata becomes arbitrary code execution inside the controller, and in a default install that controller can read every Secret in the cluster. This is CVE-2026-3288, an injection-class weakness (CWE-74) rated CVSS 8.8, and the only privilege it needs is the ability to create an Ingress.

This is not a memory-corruption exploit or a clever protocol trick. It is configuration injection: untrusted input crosses a boundary into a config file that a privileged process then loads and acts on. ingress-nginx sits at the front door of a large share of Kubernetes clusters, turning Ingress objects into live nginx configuration on every change. That translation step is the vulnerability. The Kubernetes security team published the advisory for CVE-2026-3288 alongside a cluster of siblings, CVE-2026-24512, CVE-2026-24513, CVE-2026-24514, and CVE-2026-1580, all fixed together in v1.13.8, v1.14.4, and v1.15.0 on 9 March 2026, with credit to reporter Kai Aizen. We do not publish a weaponized payload. We explain the mechanism, who can reach it, and how to know whether your clusters are exposed. Verifiable security.

How a quote becomes code

The controller's job is to convert Kubernetes Ingress objects into an nginx configuration and reload nginx. Several annotations feed values directly into that generated file. The nginx.ingress.kubernetes.io/rewrite-target annotation is the clearest example: its value is meant to become the target of a rewrite rule. The controller places that value inside a generated directive, roughly as if it were writing rewrite ... "your-value"; into the config. The intended value is a path, which the controller assumed was safe to drop into the file verbatim.

The assumption breaks the moment the value contains a quote. A " in the annotation closes the string the controller opened, and the characters after it are no longer data, they are configuration. nginx reads them as new directives on the same reload. That is the whole trick: not a buffer overflow, not a parser bug in nginx itself, just a value that was trusted to be a path being allowed to redefine the file it was written into. The same flaw reaches the path field of an Ingress rule, which is likewise rendered into the generated configuration.

Injecting configuration would be serious on its own, because nginx configuration controls routing, TLS termination, and access rules for everything behind the controller. But it is more powerful than routing. Certain directives, including module and Lua hook mechanisms available in the ingress build, can cause code to run in the controller's process. Once the attacker can write arbitrary directives, they are no longer editing routes, they are choosing what the controller executes. That is how a config-injection bug becomes remote code execution, CWE-94 territory, without ever touching nginx's own memory.

A QUOTE THAT REWRITES THE CONFIG Ingress annotation --> [ ingress-nginx controller ] --> generated nginx.conf rewrite-target templates value nginx reload value = /clean/path -> rewrite ... "/clean/path"; (intended) value = /x" <directives> -> rewrite ... "/x" <directives> (breakout) the " ends the string early; what follows is parsed as CONFIG config can load code -> execution in the controller's context default controller reads ALL Secrets -> cluster-wide disclosure

Illustrative structure of the quote breakout. No working directive payload is shown.

Why the blast radius is the whole cluster

Two facts turn this from a controller bug into a cluster event. The first is where the code runs. The ingress controller is not a low-value pod. In a default installation its service account can read Secrets across the whole cluster, because it needs TLS certificates and related material to terminate connections. Code execution in that process therefore doubles as a cluster-wide secret-disclosure primitive: database credentials, cloud tokens, service-account keys, anything held as a Secret the controller can list. The second fact is who can pull the trigger. The attacker does not need cluster-admin or a shell on a node. They need permission to create or modify Ingress objects.

In a lot of real clusters that permission is handed out freely, to a CI pipeline that deploys applications, a tenant namespace in a shared cluster, or a platform team's self-service workflow. Ingress creation reads as routine, not privileged, so it rarely sits behind the scrutiny reserved for RBAC edits or node access. That gap between how the permission feels and what this bug turns it into is the entire risk.

An Ingress looks like routing metadata. In this bug it is a write primitive into the configuration of the process that holds your cluster's Secrets.

The lifecycle problem: this class will not keep getting fixed

Treat this as more than one patch. ingress-nginx is being retired. The project has signaled that it is winding down, which means the stream of maintainers who found and fixed this injection class is drying up. CVE-2026-3288 and its siblings were caught this time. The next annotation that templates untrusted input into the config may not be, and clusters that stay on ingress-nginx past its maintenance horizon inherit that risk permanently. The fix for the specific CVE is an upgrade. The fix for the class is a migration plan and an admission-control net that does not depend on the controller staying maintained.

How to know whether you are exposed

Read these five facts before you assume you are clear

How Celvex catches this

Find. Prove. Fix. Verify.

Find

A read-only check reads the ingress-nginx controller version from the running image and inventories, through RBAC, exactly which identities can create or modify Ingress objects. No malicious annotation is sent.

Prove

An admission-time test submits a benign Ingress carrying a quote in the rewrite-target and records whether the cluster accepts it. Version evidence plus that admission result become an Ed25519-signed Proof Capsule you or your auditor can replay offline.

Fix

The capsule names the steps: upgrade to 1.13.8, 1.14.4, or 1.15.0; add an OPA or Kyverno policy blocking the rewrite-target annotation and quotes in path fields; and scope the controller's Secret access down from cluster-wide.

Verify

A fresh check confirms the fixed version is running and that the admission policy now rejects the malicious annotation. The finding closes and the verified-fix event is recorded for the audit trail.

The lesson generalizes past one controller. Any component that turns user-supplied objects into a configuration file for a privileged process is templating strings across a trust boundary, and every such boundary needs the same neutralization a database query or a shell command needs. ingress-nginx forgot it for one annotation, and the cost was code execution next to every Secret in the cluster. Ask the question everywhere it applies: what untrusted values reach my generated configs, and what can those configs make the reader do.

Verifiable security. Find it. Prove it. Fix it. Verify the fix held. That is what we ship.

Sources

Which of your clusters run an unpatched ingress-nginx, and who can create an Ingress on them?

Free Exposure Check, no signup required. We read your ingress controller versions against the fixed builds, inventory who can create Ingress objects, and ship a signed Proof Capsule for the highest-confidence finding.

Run a Free Scan →