Skip to main content
Vulnerability Database/CVE-2026-61629

CVE-2026-61629: nginx ignition DoS Vulnerability

CVE-2026-61629 is a denial of service vulnerability in nginx ignition that allows attackers to exhaust server CPU through malformed Accept-Language headers. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-61629 Overview

CVE-2026-61629 is a denial-of-service vulnerability in nginx-ignition, a user interface for the nginx web server. Versions 2.29.0 through 2.40.0 contain a flaw in the gin i18n middleware. The middleware passes the raw Accept-Language header to golang.org/x/text/language.ParseAcceptLanguage without any size or shape filtering. The underlying parser exhibits quadratic-time behaviour on long lists of malformed language tags. A single unauthenticated GET request can burn approximately 2.4 seconds of CPU on the host. Version 2.40.1 fixes this issue.

Critical Impact

Ten concurrent unauthenticated attackers can saturate a ten-core server while consuming roughly 10 MiB/s of upstream bandwidth, rendering the nginx-ignition management interface unavailable.

Affected Products

  • nginx-ignition versions 2.29.0 through 2.40.0
  • The api/common/server/i18n.go middleware component
  • Deployments exposing the nginx-ignition API server to untrusted networks

Discovery Timeline

  • 2026-09-21 - CVE-2026-61629 published to the National Vulnerability Database
  • 2026-09-23 - Last updated in NVD database

Technical Details for CVE-2026-61629

Vulnerability Analysis

The vulnerability is an algorithmic complexity attack classified under [CWE-770] Allocation of Resources Without Limits or Throttling. The gin i18n middleware executes in front of every HTTP request handled by the nginx-ignition API server. It reads the Accept-Language header verbatim and forwards it to language.ParseAcceptLanguage from golang.org/x/text. That parser runs in quadratic time when processing long sequences of malformed language tags.

The fix for CVE-2022-32149 added in golang.org/x/text v0.3.8 caps the number of - characters at 1000. However, the guard does not cap _ characters. The parser's internal scanner aliases _ to - before parsing, which allows attackers to bypass the guard entirely by substituting underscores for hyphens.

Root Cause

The middleware performed no validation of the Accept-Language header length or structure before invoking the parser. Combined with an incomplete upstream guard in golang.org/x/text, this allowed unauthenticated clients to trigger the parser's worst-case quadratic behaviour and consume disproportionate CPU per request.

Attack Vector

An unauthenticated remote attacker sends a GET request to any nginx-ignition API endpoint with an Accept-Language header composed of many _ separators. A single request consumes about 2.4 seconds of server CPU. Ten concurrent attackers saturate a ten-core server for the duration of the attack. No authentication, user interaction, or special privileges are required.

go
// Patch applied in api/common/server/i18n.go
import (
    "context"
    "strings"

    "github.com/gin-gonic/gin"
    "golang.org/x/text/language"

    "dillmann.com.br/nginx-ignition/core/common/i18n"
)

const maximumLanguageTags = 10

func i18nMiddleware(commands i18n.Commands) gin.HandlerFunc {
    return func(ginCtx *gin.Context) {
        lang := commands.DefaultLanguage()

        langHeader := ginCtx.GetHeader("Accept-Language")
        if strings.Count(langHeader, "-")+strings.Count(langHeader, "_") > maximumLanguageTags {
            langHeader = ""
        }

        tags, _, err := language.ParseAcceptLanguage(langHeader)
        if err == nil && len(tags) > 0 {
            for _, tag := range tags {
// Source: https://github.com/lucasdillmann/nginx-ignition/commit/0c988fc1277c7d291725e8373313f8486fa1b31a

The patch counts both - and _ characters and discards the header when the combined total exceeds ten, preventing the parser from processing pathological inputs.

Detection Methods for CVE-2026-61629

Indicators of Compromise

  • HTTP requests to nginx-ignition endpoints containing Accept-Language header values with dozens or more _ characters
  • Sustained high CPU utilization on the nginx-ignition process without corresponding legitimate request volume
  • Elevated request latency across all API endpoints during periods of low traffic
  • Repeated requests from a small set of source IPs preceding CPU saturation events

Detection Strategies

  • Inspect reverse proxy or load balancer logs for Accept-Language header values exceeding a reasonable length threshold, such as 100 bytes
  • Correlate spikes in per-request processing time on nginx-ignition endpoints with abnormal header characteristics
  • Alert when a single client IP issues repeated requests carrying malformed language tag lists

Monitoring Recommendations

  • Enable CPU and request-latency metrics on the nginx-ignition host and set thresholds for sustained utilization above baseline
  • Capture and retain full HTTP request headers in centralized logs to support retrospective analysis
  • Monitor upstream bandwidth consumption on the interface serving nginx-ignition for sustained increases in inbound traffic

How to Mitigate CVE-2026-61629

Immediate Actions Required

  • Upgrade nginx-ignition to version 2.40.1 or later, which enforces a maximum of ten language tag separators in the Accept-Language header
  • Restrict network access to the nginx-ignition management interface to trusted administrative networks or VPN endpoints
  • Place a reverse proxy or WAF in front of nginx-ignition to strip or normalize oversized Accept-Language headers
  • Rate-limit unauthenticated requests to the API server at the network edge

Patch Information

The fix is committed in GitHub commit 0c988fc and released in nginx-ignition version 2.40.1. Full advisory details are available in GHSA-jr34-h97m-9hpx. Operators unable to upgrade should apply the middleware guard as a local patch.

Workarounds

  • Configure a fronting nginx or reverse proxy to drop the Accept-Language header on incoming requests to nginx-ignition
  • Enforce a maximum header size at the proxy layer that rejects oversized Accept-Language values
  • Apply strict per-source-IP rate limiting to unauthenticated endpoints of the nginx-ignition API server
bash
# nginx reverse proxy example: cap Accept-Language length and rate-limit clients
limit_req_zone $binary_remote_addr zone=ignition:10m rate=5r/s;

server {
    listen 443 ssl;
    server_name ignition.example.com;

    location / {
        limit_req zone=ignition burst=10 nodelay;

        if ($http_accept_language ~* ".{100,}") {
            return 400;
        }

        proxy_set_header Accept-Language "";
        proxy_pass http://127.0.0.1:8080;
    }
}

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.