Learn More about Benny Czarny's Book Cybersecurity Upside Down

Learn More
We utilize artificial intelligence for site translations, and while we strive for accuracy, they may not always be 100% precise. Your understanding is appreciated.

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

By OPSWAT

May 2025 marked the public disclosure of a critical security vulnerability, CVE-2025-1974, dubbed IngressNightmare, affecting the Kubernetes ingress-nginx controller widely deployed across cloud native infrastructures. This vulnerability allows unauthenticated attackers to inject arbitrary configurations into NGINX, potentially leading to unauthorized RCE (remote code execution) and full cluster compromise.

As part of the OPSWAT Fellowship program, our fellows conducted an in-depth technical analysis to better understand its root cause, exploitation path, and mitigation strategies surrounding this high-severity issue.

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

Overview of CVE-2025-1974

CVE-2025-1974 is a critical template injection vulnerability identified in ingress-nginx versions up to 1.11.4 and specifically 1.12.0. Attackers with node-level access to a Kubernetes cluster can exploit this flaw to execute arbitrary code using RCE via the ingress-nginx controller which, by default, has extensive privileges, including access to critical secrets within the cluster.

The Kubernetes Security Response Committee assigned this vulnerability with a CVSS v3.1 score of 9.8 (critical severity):

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

Key Components in this Analysis

Kubernetes Overview

Kubernetes (K8s) is an open-source platform for automating deployment, scaling, and operational management of containerized applications. Kubernetes clusters typically consist of multiple machines, which can include both physical hardware and virtual machines, working collectively to provide highly available, scalable, and manageable application environments.

NGINX Ingress Controller

NGINX ingress controller (ingress-nginx) is an open-source ingress controller built on top of the NGINX web server. It operates within a Kubernetes cluster, functioning primarily as a reverse proxy and load balancer. This controller interprets Ingress resources defined by users and translates them into actionable NGINX configurations to route traffic flow into and within the cluster.

AdmissionReview and Its Role

Ingress-nginx integrates with Kubernetes using a webhook service called AdmissionReview. This service is crucial for processing native Kubernetes Ingress objects and translating them into validated and syntactically correct NGINX configurations. While AdmissionReview ensures configuration accuracy, it operates independently of the ingress-nginx controller and generally lacks stringent authentication controls. This lack of strict authentication is a key factor that contributed to the exploitability of CVE-2025-1974.

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

Vulnerability Exploitation and Technical Analysis

Exploitation Mechanism

At its core, the exploitation of CVE-2025-1974 starts with a malicious request. Attackers craft a malicious request to the AdmissionReview webhook, forcing NGINX to dynamically load a shared library at runtime. Based on this mechanism, our fellows analyzed both the AdmissionReview webhook and the NGINX workflow to understand this exploit path.

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

Template Injection Vulnerability

On AdmissionReview webhook, when processing incoming requests, the CheckIngressfunction transforms Kubernetes Ingress Objects into valid NGINX configuration files. The flow proceeds as follows:

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation
  1. Each configuration is parsed and passed to generateTemplate to be formatted according to predefined NGINX templates.
  2. Subsequently, testTemplate validates the generated configuration against the underlying NGINX binary.

All NGINX configurations are based on predefined templates found in the nginx.tmpl file within the ingress-nginx source code:

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

Within the generateTemplatefunction, the configuration is processed as shown in the following code snippet:

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

However, input validation and sanitization are insufficient. Specifically, the uidfield from an Ingress Object is directly inserted into the NGINX configuration template, creating an injection point. An attacker can exploit this by supplying crafted input such as uid="1234#;\n\n}\n}\n}\n injection_value".

This malicious input allows global scope injection into the NGINX template, enabling attackers to trigger arbitrary NGINX directives and potentially achieve RCE.

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

From Template Injection to Remote Code Execution

The testTemplate() Function Explained

After the NGINX configuration is generated by the generateTemplatefunction, the testTemplatefunction creates a temporary configuration file and runs the NGINX library with the command nginx -c {config_file} -t. This forces the NGINX binary to parse and validate the configuration.

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

To exploit the vulnerability, an attacker needs to identify a directive capable of executing malicious code. Initially, our fellows identified the load_moduledirective as potentially useful, because this directive allows NGINX to load external plugins. However, this directive is only permitted in the early phase of configuration parsing, which does not match our injection point.

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation
IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

To solve this challenge, we continued further research, which led to the ssl_enginedirective, described as "The module may be dynamically loaded by OpenSSL during configuration testing." This raised curiosity due to its capability to dynamically load modules, necessitating a deeper examination.

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

Understanding the ssl_engine Directive

To gain a deeper understanding of how NGINX handles the ssl_enginedirective, as well as determining the conditions under which NGINX permits dynamic loading of additional modules via this directive, we looked into the NGINX source code.

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

On startup, NGINX loads its initial state, then parses configuration files line by line. Each directive is handled by the nginx_command_tstructure, with the directive ssl_enginedirectly invoking the ngx_openssl_commands.

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation
Figure 1. ngx_command_s definition
IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation
Figure 2 ssl_engine ngx_command_t structure

Upon analyzing the ngx_openssl_commandsfunction, our fellows discovered that it relies on OpenSSL support, specifically the function ENGINE_by_idwhich is used for hardware-accelerated SSL modules.

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

And while analyzing the ENGINE_by_idfunction, we determined that it enables the dynamic loading of shared libraries. Moreover, if the library is compiled with the __attribute__((constructor)) extension, the associated function can be executed immediately upon loading. This indicates that by exploiting the ssl_enginedirective, an attacker could load arbitrary shared libraries on the host, potentially leading to RCE.

Targeting Shared Libraries and Attack Strategy

To reliably facilitate code execution, the next step involves identifying a shared library. Rather than relying on external libraries, a more viable and controlled approach emerges from NGINX’s own behavior: the client body buffer mechanism. This feature enables NGINX to offload large incoming requests into temporary files, opening opportunities for exploitation based on predictable file handling behavior.

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

By default, when an incoming request exceeds 8KB, NGINX writes the request body to a temporary file located at /tmp/nginx/client-body, using a filename in the format cfg-{random_value}. These temporary files are retained for up to 60 seconds between successful chunks of a received message.

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

After writing a partial request body to a temporary file, NGINX defers deletion until the entire body is received. If the request remains incomplete and no data is received for up to 60 seconds, the file is eventually purged. However, by intentionally withholding the final chunk of data, an attacker can keep the temporary file in use, making it exploitable.

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

Although the uploaded file content can be controlled, locating it on the file system is difficult due to the randomized filename. The storage path can be configured using client_body_temp_path, but the filename is randomly generated at runtime, making it unpredictable. This randomness significantly hinders targeted access even through brute force. To overcome this, the team leveraged behaviors inherent to the Linux OS. Consider the following example:

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

This code opens a file and keeps it in an active state, closely mimicking the behavior of NGINX's client body buffer mechanism. Using /proc/{pid}/fd directory, attackers can find symbolic links created by the Linux kernel that map open file descriptors to their corresponding file paths. This route allows attackers to reduce the brute-force space to only two variables: the process ID (pid) and the file descriptor (fd).

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

Simulating Exploitation

Based on the analysis above, a practical exploitation approach for RCE within the Ingress-NGINX pod is:

  1. Upload a malicious shared library using NGINX's client body buffer mechanism to store it temporarily on the file system.
  2. Use template injection to initiate a brute force attempt that forces NGINX to load the previously uploaded shared library via vulnerable directives.
IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

Crafting the Payload Containing the Shared Library

To ensure code execution upon loading, an entrypoint function with constructor extension is defined within the malicious shared library. This function is executed upon loading by NGINX and is designed to establish a reverse shell connection to a remote host.

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

After compilation, the size of the resulting shared library comfortably exceeded 8KB, allowing it to be buffered by NGINX without requiring additional padding.

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

Our fellows then crafted a request with an inflated Content-Lengthvalue (e.g., 1MB) to introduce a size mismatch. This caused NGINX to buffer the entire body rather than processing it immediately, ensuring the shared object would be written to a predictable location.

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

Triggering the Shared Library Through Injection

With the shared library in place, we next injected a malicious directive into the NGINX configuration using the vulnerable uidfield. This directive included ssl_enginepointing to the buffered file path:

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

Successful RCE requires the ssl_enginedirective to reference the correct path to the buffered file. This can be achieved via an automated brute force script that systematically iterates over possible combinations of process IDs and file descriptors to identify the valid symbolic link pointing to the buffered shared object.

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

Below is a sample of the generated NGINX template that triggered the exploit.

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

Upon successful exploitation, the attacker could gain shell access under the context of the ingress-nginx pod, which by default had access to sensitive Kubernetes cluster secrets.

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

Mitigation and Remediation

To effectively mitigate the risks associated with CVE-2025-1974, organizations require a solution that provides visibility and control over their open-source components.

OPSWAT SBOM, a foundational technology within the MetaDefender® platform, addresses this need by providing an inventory of all software components, libraries, Docker containers, and dependencies in use. It allows organizations to track, secure, and update their components proactively.

IngressNightmare: CVE-2025-1974 Remote Code Execution Vulnerability & Remediation

In the example above, the SBOM technology in MetaDefender Core™ scanned the nginx-ingress-controller package that contained the CVE-2025-1974 vulnerability. The system automatically flagged the issue as Critical and provided guidance on fixed versions available, enabling teams to quickly prioritize and patch the vulnerability before it can be exploited.

OPSWAT SBOM is available in MetaDefender Core and MetaDefender Software Supply Chain™, enabling security teams to identify and act on vulnerabilities faster. With OPSWAT SBOM, security teams can:

  • Quickly locate vulnerable components - Immediately identify the open-source components affected by deserialization attacks. This ensures swift action in either patching or replacing the vulnerable libraries. 
  • Ensure proactive patching and updates - Continuously monitor open-source components through OPSWAT SBOM to stay ahead of deserialization vulnerabilities. OPSWAT SBOM can detect outdated or insecure components, enabling timely updates and reduced exposure to attacks. 
  • Maintain compliance and reporting – OPSWAT SBOM helps organizations meet compliance requirements as regulatory frameworks increasingly mandate transparency in software supply chains.

Stay Up-to-Date With OPSWAT!

Sign up today to receive the latest company updates, stories, event info, and more.