flawopen.com/Teardowns/cve-2024-7646-ingress-nginx-annotation-code-injection
CVE-2024-7646: Ingress-NGINX Validation Bypass
A carriage-return bypass enabled command injection and access to controller credentials. Fixed in 1.11.2/1.10.4; ingress-nginx is retired.
Imagine a gatekeeper that checks whether a form contains an allowed word but fails to check the whole value. A carriage return can change how the next system reads the remaining text. Here, an annotation passed a partial regex check and was later written into generated NGINX configuration. The fix validates the complete value and handles carriage returns safely.
Core Concepts & Subsystem Terms
Ingress object- A Kubernetes API resource that describes routing from an external host or path to a Service; users may have permission to create these without cluster-admin rights.
Annotation validation bypass- An annotation value passed a validator that matched only an allowed substring instead of requiring the complete value to be one of the permitted options.
Carriage return (`\r`)- A control character used as a line break in some formats. If validation and downstream configuration generation interpret it differently, it can change where configuration lines begin.
Controller service account- The Kubernetes identity used by the ingress-nginx controller. The upstream security notice says its default permissions can include access to all cluster Secrets.
Framework mappings
- CWE reference for the weakness described in this guide: CWE-20
Root Cause Analysis
CVE-2024-7646 is an annotation-validation bypass in ingress-nginx, not the unrestricted use of a custom Lua snippet. The auth-tls-verify-client validator used a Go regular expression without start and end anchors, so MatchString could accept a value containing a valid option as only a substring. A carriage return in the annotation could then be interpreted differently while the controller cleaned generated NGINX configuration. The upstream fix tightens the option regex to match the entire value and updates cleanConf to handle bare carriage returns safely. The Kubernetes security notice says an actor who can create Ingress objects can bypass validation, inject commands, and obtain the controller credentials; in the default configuration those credentials can read all cluster Secrets. This is a high-severity, authenticated Kubernetes API path (CVSS 8.8), not an unauthenticated request from any network client. The project was retired in March 2026, so upgrading to a historical fix is only an immediate containment step; deployments should migrate to a maintained controller or Gateway API implementation.
Step-by-Step Attack Flow
A user can create an Ingress
The attacker needs Kubernetes API permission to create an Ingress object. The issue is especially relevant in multi-tenant clusters where that permission is delegated to application teams.
An annotation passes a partial match
The vulnerable auth-tls-verify-client regular expression lacked anchors. Go MatchString could therefore accept a longer value containing an allowed option, rather than requiring an exact permitted value.
Carriage-return handling crosses the config boundary
The annotation is incorporated into generated NGINX configuration. The patch series fixes both whole-value validation and handling of bare carriage returns during config cleanup, closing the mismatched interpretation path.
The controller identity is exposed
The Kubernetes security notice says successful command injection can obtain the ingress-nginx controller credentials. In the default configuration, that service account can access all cluster Secrets; the impact depends on the deployed RBAC permissions.
Source Code: Flaw vs. Secure Implementation
These are excerpts from the upstream fixes for CVE-2024-7646: PR #11719 anchors the allowed auth-tls-verify-client values, and PR #11721 handles bare carriage returns in cleanConf. The 1.10 branch received the corresponding #11718 and #11722 changes. The code shown omits unrelated surrounding function logic.
// internal/ingress/annotations/authtls/main.go (before)
authVerifyClientRegex = regexp.MustCompile(`on|off|optional|optional_no_ca`)
// internal/ingress/controller/template/template.go (before)
switch c {
case ' ', '\t':
needOutput = lineStarted
case '\n':
needOutput = !(!lineStarted && emptyLineWritten)
nextLineStarted = false
}
// internal/ingress/annotations/authtls/main.go (fixed)
authVerifyClientRegex = regexp.MustCompile(`^(on|off|optional|optional_no_ca)$`)
// internal/ingress/controller/template/template.go (fixed)
switch c {
case '\r':
rest := in.Bytes()
if len(rest) > 0 && rest[0] != '\n' {
c = ' '
needOutput = lineStarted
}
case '\n':
needOutput = !(!lineStarted && emptyLineWritten)
nextLineStarted = false
}
Engineering & System Hardening Checklist
- ✓Restrict Kubernetes RBAC permission to create or edit Ingress objects, especially in multi-tenant clusters; users with this permission could reach the vulnerable path.
- ✓For historical containment, upgrade to ingress-nginx 1.11.2 or later in the 1.11 line, or 1.10.4 or later in the 1.10 line. Check the exact vendor image and chart version.
- ✓Review Kubernetes audit logs for Ingress annotations containing carriage returns (
\r), includingnginx.ingress.kubernetes.io/auth-tls-verify-client, as directed by the upstream notice. - ✓Do not treat
allow-snippet-annotations: "false"as a fix for this CVE: the affected path was annotation validation and config line handling, not only the optional snippet feature. - ✓Ingress NGINX was retired in March 2026. Plan migration to a maintained ingress controller or Gateway API implementation; the historical CVE patch does not provide future security updates.
Sources
- Kubernetes security response — CVE-2024-7646, scope, versions, detection and mitigation
- Upstream fix — anchor auth-tls-verify-client values (PR #11719)
- Upstream fix — clean carriage returns in generated configuration (PR #11721)
- NVD — CVE-2024-7646
- Kubernetes — Ingress NGINX retirement and migration guidance
- MITRE CWE-20 — Improper Input Validation