Sep 21, 2026·7 min read·4 visits
Unauthenticated remote CPU amplification vulnerability in nginx-ignition version 2.29.0 through 2.40.0 allowed attackers to trigger a Denial of Service (DoS) by sending crafted Accept-Language headers with excessive underscore separators.
A vulnerability exists in the i18n middleware of nginx-ignition, enabling CPU amplification attacks. By transmitting a crafted Accept-Language header containing malformed tags separated by underscores, an unauthenticated remote attacker can bypass the length-guard threshold of the underlying Go parsing library. Normalization of underscores to hyphens occurs after the initial validation checks, forcing the parser into expensive quadratic-time loops that consume 100% of available CPU resources. This leads to a complete denial of service for the administrative API and potentially degrades the availability of the hosting system. This vulnerability has been resolved in version 2.40.1.
The administrative user interface nginx-ignition exposes several API endpoints for managing Nginx configurations, system status, and administrative routing. Among these components is an internationalization middleware, denoted as i18nMiddleware, designed to detect and apply language preferences dynamically based on the client's request headers. This middleware intercepts all incoming HTTP traffic prior to routing execution, meaning that both authenticated and unauthenticated endpoints execute this component upon receiving a request.\n\nThe attack surface is highly exposed because the middleware acts globally. Any user capable of establishing a TCP connection to the nginx-ignition API port can trigger the vulnerability without providing credentials or session identifiers. This exposes the system to unauthenticated remote exploitation, specifically targeting resource management mechanisms.\n\nThe vulnerability is classified under CWE-770 (Allocation of Resources Without Limits or Throttling). By failing to validate the structure and composition of the Accept-Language header before parsing, the system allows the underlying parsing library to allocate excessive CPU cycles. The vulnerability results in a total exhaustion of CPU resources on the hosting machine, degrading service availability for legitimate administrative tasks.
To comprehend the root cause of CVE-2026-61629, one must examine the internal parser logic of the Go text processing package golang.org/x/text/language. When a client transmits an HTTP request, the global middleware extracts the Accept-Language header and immediately passes it to the language.ParseAcceptLanguage function. This function is responsible for parsing BCP 47 language tags, which are typically formatted with hyphen-separated subtags, such as en-US or zh-CN.\n\nThe parsing algorithm utilizes an internal tokenization loop that identifies and processes individual language subtags. If the parser encounters subtags that do not conform to the expected format, it enters error-recovery routines. In earlier versions of the library, processing exceptionally long malformed sequences led to quadratic-time complexity due to repeated calls to an internal function named gobble. This function performs buffer shifting via runtime.memmove to slice and discard invalid inputs, resulting in extreme CPU cycle consumption when handling large payloads.\n\nA previous vulnerability, tracked as CVE-2022-32149, was addressed by capping the number of hyphen characters processed during parsing to 1,000. However, the parser's scanner normalizes underscore separators into hyphens during tokenization. This normalization occurs after the initial input-validation checks. Because the initial delimiter count check only scanned for hyphens and did not account for underscores, an attacker can substitute underscores for hyphens to bypass the 1,000-delimiter threshold entirely.\n\nmermaid\ngraph LR\n A[\"Client Request\"] --> B[\"i18nMiddleware Interception\"]\n B --> C[\"Check Accept-Language Header\"]\n C --> D[\"Verify Delimiter Count\"]\n D --> E[\"Normalized Tokenization\"]\n E --> F[\"golang.org/x/text/language Parser\"]\n F --> G[\"Quadratic Loop (gobble)\"]\n G --> H[\"CPU Exhaustion\"]\n
The vulnerability manifests in api/common/server/i18n.go within the nginx-ignition codebase. In the vulnerable version, the Accept-Language header is retrieved and immediately evaluated without prior length or delimiter validation.\n\ngo\n// Vulnerable Implementation\nfunc i18nMiddleware(commands i18n.Commands) gin.HandlerFunc {\n\treturn func(ginCtx *gin.Context) {\n\t\tlang := commands.DefaultLanguage()\n\n\t\tlangHeader := ginCtx.GetHeader(\"Accept-Language\")\n\t\t// The unvalidated header string is passed directly to the parser\n\t\ttags, _, err := language.ParseAcceptLanguage(langHeader)\n\n\nTo remediate this vulnerability at the application layer, the developer introduced a check to limit the cumulative count of both hyphens and underscores before the library parser is invoked. The workaround establishes a maximum threshold of 10 delimiters, discarding the header if it exceeds this count.\n\ngo\n// Patched Implementation\nconst maximumLanguageTags = 10\n\nfunc i18nMiddleware(commands i18n.Commands) gin.HandlerFunc {\n\treturn func(ginCtx *gin.Context) {\n\t\tlang := commands.DefaultLanguage()\n\n\t\tlangHeader := ginCtx.GetHeader(\"Accept-Language\")\n\t\t// Count both hyphens and underscores to prevent delimiter-based bypasses\n\t\tif strings.Count(langHeader, \"-\")+strings.Count(langHeader, \"_\") > maximumLanguageTags {\n\t\t\tlangHeader = \"\"\n\t\t}\n\n\t\ttags, _, err := language.ParseAcceptLanguage(langHeader)\n\n\nThe application-level fix effectively mitigates the issue by truncating the parsed header to an empty string when anomalous delimiter patterns are detected. A secondary, more robust fix was applied by upgrading the compiler environment to Go 1.25.6. This upgrade forces the compilation of dependencies against patched versions of golang.org/x/text where the upstream parser natively accounts for underscore characters during the initial input verification phase.
Exploitation of CVE-2026-61629 is straightforward and requires no prior authentication, special configuration, or specific state. The attacker must construct a malformed Accept-Language header containing a high density of underscore characters. This payload takes advantage of the fact that Go's HTTP server implementation permits large headers (up to 1 MiB by default), allowing the attacker to send a substantial payload within a single request.\n\nThe sequence of the attack starts with target identification. The attacker probes the nginx-ignition administrative interface to confirm that the API service is reachable. Once identified, the attacker crafts a single HTTP GET request targeting any public endpoint, such as /api/i18n or /api/healthcheck, injecting the malformed header into the transaction.\n\nbash\ncurl -H \"Accept-Language: ________________________________________________________________________________\" http://target-host:8080/api/i18n\n\n\nWhen this request is processed, the i18nMiddleware extracts the header and invokes the parser. The parser converts each underscore into a hyphen, enters the error recovery state, and executes expensive memory-shifting operations. A single HTTP request containing a dense underscore payload of approximately 65,000 characters is sufficient to block a single CPU core for approximately 2.4 seconds. Multiple concurrent requests can easily saturate all available cores on the host, rendering the service completely unresponsive.
The primary impact of CVE-2026-61629 is a severe Denial of Service affecting the availability of the host operating system's CPU resources. Because nginx-ignition runs as an administrative control panel, CPU starvation prevents administrators from executing commands, viewing logs, or modifying configurations. If the UI is deployed on the same system running the core Nginx proxy, the high CPU load can degrade proxying capabilities, leading to packet loss and high latency for transit traffic.\n\nThe CVSS v3.1 score is evaluated at 7.5, reflecting a High severity rating. The vector is defined as CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H. The attack is network-accessible, requires low complexity, lacks authentication requirements, and demands no user interaction. The scope remains unchanged because the impacted resource is the application server itself.\n\nWhile confidentiality and integrity remain unaffected by this vulnerability, the low barrier to entry and the absence of pre-requisites make it an attractive target for automated disruption campaigns. Because the payload size is small relative to the CPU cycles consumed, the attack yields an amplification factor of approximately 75x, making it highly effective even when initiated from low-bandwidth connections.
The primary and recommended resolution for CVE-2026-61629 is to upgrade the nginx-ignition deployment to version 2.40.1 or later. This release incorporates the application-level delimiter filter and upgrades the Go base image to version 1.25.6, ensuring that the upstream golang.org/x/text package contains the official fix for the parsing bypass.\n\nFor environments where immediate binary updates are not feasible, network-level and proxy-level mitigations should be implemented. Administrators can configure front-end load balancers or upstream reverse proxies, such as Nginx or HAProxy, to inspect and filter incoming Accept-Language headers. This blocks the malicious payload before it reaches the nginx-ignition middleware.\n\nAn exemplary Nginx configuration block can be placed in the reverse proxy configuration to detect and drop requests containing an excessive number of underscores or hyphens:\n\nnginx\n# Drop requests with suspicious Accept-Language headers\nif ($http_accept_language ~* \"([_-].*?){10,}\") {\n return 400;\n}\n\n\nDeploying this rule effectively terminates the request at the reverse proxy layer, saving the backend API from executing the resource-intensive parsing operations. Additionally, administrators should restrict access to the nginx-ignition port, ensuring that it is only accessible from trusted IP addresses or internal networks.
| Attribute | Detail |
|---|---|
| CWE ID | CWE-770 |
| Attack Vector | Network |
| CVSS Score | 7.5 |
| EPSS Score | 0.0 |
| Exploit Status | PoC |
| KEV Status | Not Listed |
nginx-ignition is a web-based user interface for managing the Nginx web server. In versions 2.33.0 through 2.35.0, the application is vulnerable to an improper authentication flaw (CWE-287) in its Multi-Factor Authentication (MFA) implementation. The stateless validation of Time-Based One-Time Passwords (TOTP) allows an attacker to reuse a captured, active verification code multiple times within the standard 30-second validity window, successfully bypassing secondary authentication checks if primary credentials are known.
Nginx Ignition prior to version 2.41.1 contains a Time-of-Check to Time-of-Use (TOCTOU) race condition in its unauthenticated onboarding API endpoint. This flaw allows remote, unauthenticated attackers to register an administrative account by sending concurrent HTTP requests during the initial system configuration phase, bypassing the check meant to restrict onboarding to a single initial administrator.
A logic error in Hatchet's OAuth state validation mechanism allows unauthenticated remote attackers to bypass state parameter verification. By submitting an empty state parameter, attackers can exploit an equality collision with cleared session keys, facilitating Login Cross-Site Request Forgery (Login CSRF) or Session Fixation.
A high-severity access control vulnerability in ToolHive CLI before v0.30.1 and ToolHive Studio before v0.38.0 allows local containerized MCP servers to bypass network isolation. This enables malicious workloads to establish TCP/IP connections to administrative and control plane endpoints exposed on the host loopback interface.
AnyCable is a real-time communication server. Prior to version 1.6.15, its Pusher-compatible REST API suffered from an authentication bypass vulnerability because it failed to verify that the request body matched the signature-validated body_md5 parameter. This allows attackers to perform replay attacks with modified body contents.
A denial-of-service vulnerability exists in AnyIO prior to version 4.14.2. Standard error streams of process-pool workers are connected to an operating system pipe that is never drained by the parent process. This allows a worker to fill the pipe buffer and deadlock indefinitely.