CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-11417

CVE-2026-11417: OS Command Injection in AWS CDK NodejsFunction Bundling Pipeline

Amit Schendel
Amit Schendel
Senior Security Researcher

Jun 15, 2026·9 min read·3 visits

Executive Summary (TL;DR)

Unsanitized input interpolation in the AWS CDK NodejsFunction bundling component allows unauthenticated local command execution during infrastructure synthesis (cdk synth).

A critical supply-chain OS command injection vulnerability exists in the NodejsFunction local bundling pipeline within the AWS Cloud Development Kit (CDK) library (aws-cdk-lib) before version 2.245.0 (and before 2.246.0 on Windows systems). The vulnerability allows a threat actor who can control any of several bundling properties (externalModules, define, loader, inject, or esbuildArgs) to execute arbitrary operating system commands on the host machine running the CDK compilation or deployment toolchain (e.g., during cdk synth, cdk deploy, or cdk diff).

Vulnerability Overview

The AWS Cloud Development Kit (CDK) is an open-source software development framework to define cloud infrastructure in code and provision it through AWS CloudFormation. Within this framework, the NodejsFunction construct (under the @aws-cdk/aws-lambda-nodejs package or aws-cdk-lib/aws-lambda-nodejs) abstracts the process of compiling, bundling, and packaging JavaScript or TypeScript code for AWS Lambda. Under the hood, this construct leverages esbuild to compile target source entries, bundle associated dependencies, and output an archive optimized for cloud deployment. This pipeline executes automatically during the synthesis phase, which converts high-level programming language code into CloudFormation templates.

A critical supply-chain OS command injection vulnerability (classified as CWE-78) exists in the local bundling implementation of this construct. An attacker who can control specific configuration parameters can inject malicious OS shell metacharacters. Because these parameters are subsequently passed directly to the local shell environment during compilation, the payload executes on the host workstation or automated build runner. This execution operates with the execution privileges of the user initiating the synthesis process, typically a developer or a highly privileged continuous integration (CI) service.

The attack surface is particularly severe because the vulnerability manifests during infrastructure synthesis rather than deployment or runtime. Standard client-side secure-install configurations, such as utilizing the --ignore-scripts flag during package installation, fail to mitigate this threat because the code executes within standard TypeScript code paths rather than lifecycle hooks. Consequently, this vulnerability opens up significant supply-chain pathways. Threat actors can exploit the vulnerability by publishing malicious packages containing custom wrapper constructs, or by submitting pull requests containing modified bundling configurations to open-source repositories.

Root Cause Analysis

The vulnerability stems from the direct concatenation of user-supplied bundling parameters into an operating system shell command. When NodejsFunction utilizes local bundling, the AWS CDK CLI runtime attempts to invoke esbuild locally rather than spawning a Docker container. The underlying logic builds a shell command dynamically using an array of arguments representing various compiler flags and values. Unescaped configuration parameters are directly interpolated into this argument array.

Specifically, the vulnerable code in bundling.ts processes configuration fields including externalModules, loader, define, inject, and esbuildArgs. These fields allow developers to customize the behavior of the compilation process by specifying external dependencies, file loaders, preprocessor definitions, and raw arguments. The code constructs an array of strings representing the final command line, joining the array with spaces to form a single execution string. This raw string is then passed to a process execution wrapper that spawns /bin/bash -c on POSIX systems or cmd.exe /c on Windows systems.

Because the runtime performs no validation, escaping, or sanitization on these configuration fields, shell metacharacters such as &, ;, |, or backticks passed within these strings act as command separators. When the shell interprets the compiled execution string, it reads these characters as instructions to split the commands. This results in the sequential or parallel execution of the original compiler call and the injected attacker payload. The command executes under the same environment context and privileges as the CDK CLI process.

Code-Level Patch Analysis

To address this vulnerability, the AWS CDK engineering team released a sequence of security updates. The primary fix, implemented in Pull Request #37292, completely refactors how local execution occurs. The vulnerability mitigation centers on migrating from shell-based command string execution to direct process spawning. By passing an array of arguments to Node's child_process.spawnSync with { shell: false }, the operating system loads the executable binary directly without executing a shell interpreter. This ensures that command line arguments are passed as discrete strings to the target program's execution vector rather than parsed by a command shell, preventing command injection.

// Pre-Patch Code (aws-lambda-nodejs/lib/bundling.ts)
// Dynamic assembly of a single CLI command string via interpolation
const esbuildCommand: string[] = [
  options.esbuildRunner,
  '--bundle', `"${relativeEntryPath}"`,
  `--target=${this.props.target ?? toTarget(scope, this.props.runtime)}`,
  '--platform=node',
  ...this.externals.map(external => `--external:${external}`),
  ...loaders.map(([ext, name]) => `--loader:${ext}=${name}`),
  ...defines.map(([key, value]) => `--define:${key}=${JSON.stringify(value)}`),
  ...this.props.inject ? this.props.inject.map(i => `--inject:"${i}"`) : [],
  ...this.props.esbuildArgs ? [toCliArgs(this.props.esbuildArgs)] : [],
];
 
const localCommand = esbuildCommand.join(' ');
exec(
  osPlatform === 'win32' ? 'cmd' : 'bash',
  [osPlatform === 'win32' ? '/c' : '-c', localCommand],
  { env: { ...process.env }, cwd }
);
// Patched Code (aws-lambda-nodejs/lib/bundling.ts)
// Transitioned to structured BundlingStep types avoiding direct shell execution
type BundlingStep =
  | { type: 'shell'; commands: string[] }
  | { type: 'spawn'; command: string[]; cwd?: string }
  | { type: 'callback'; operation: () => void };
 
// Execution of the 'spawn' step bypasses the shell entirely
if (step.type === 'spawn') {
  const [command, ...args] = step.command;
  const result = spawnSync(command, args, {
    cwd: step.cwd ?? cwd,
    env: { ...process.env, ...environment },
    stdio: ['ignore', 'pipe', 'pipe'],
  });
  if (result.status !== 0) {
    throw new Error(`Command failed with status ${result.status}`);
  }
}

A secondary patch, Pull Request #37412, was introduced to resolve an operating system regression. On Windows systems running Node.js v22 or higher, executing .cmd or .bat shims directly via spawnSync without shell wrapping triggers an OS-level EINVAL error. To resolve this while preventing command injection, the patch routes execution through powershell.exe but strictly escapes all arguments using a new powershellEscape utility. This ensures arguments are treated strictly as string literals inside the PowerShell environment.

// PowerShell Escaping Utility in PR #37412
function powershellEscape(arg: string): string {
  // Escape single quotes inside single-quoted strings by doubling them
  return "'" + arg.replace(/'/g, "''") + "'";
}
 
if (osPlatform === 'win32') {
  // Route via powershell and join arguments using the call operator
  exec('powershell.exe', [
    '-NoProfile',
    '-Command',
    `& ${step.command.map(powershellEscape).join(' ')}`
  ], {
    cwd: step.cwd ?? cwd,
    env: { ...process.env, ...environment }
  });
}

Exploitation Methodology & Proof of Concept

Exploitation of CVE-2026-11417 requires an attacker to inject a shell metacharacter into one of the configurable properties of the NodejsFunction bundling properties. This control can be achieved via a direct modification in a pull request to a target repository, or by publishing a malicious npm package containing a custom CDK construct wrapper that inherits from NodejsFunction and injects the payload under the hood. The target system must then perform infrastructure synthesis.

To demonstrate this behavior, a simple proof of concept can be established by configuring a stack containing a single NodejsFunction. By manipulating the externalModules parameter within the bundling configuration, an attacker can append a command separator and an arbitrary operating system command. When cdk synth is executed, the injection triggers immediately.

import * as cdk from 'aws-cdk-lib';
import { Stack } from 'aws-cdk-lib';
import { NodejsFunction } from 'aws-cdk-lib/aws-lambda-nodejs';
import { Runtime } from 'aws-cdk-lib/aws-lambda';
import * as path from 'path';
 
export class VulnerableStack extends Stack {
  constructor(scope: cdk.App, id: string) {
    super(scope, id);
    
    new NodejsFunction(this, 'ExploitTarget', {
      entry: path.join(__dirname, 'lambda', 'handler.ts'),
      runtime: Runtime.NODEJS_20_X,
      bundling: {
        // Injection payload uses the '&' shell metacharacter
        // This runs the shell command immediately following esbuild invocation
        externalModules: ['aws-sdk & echo "EXPLOIT_SUCCESSFUL" > /tmp/pwned.txt'],
      },
    });
  } 
}

Executing cdk synth on a system running an affected version of aws-cdk-lib results in the execution of the injected command block. The shell separates the executing processes, running the compiler and then executing the second command. This creates the file /tmp/pwned.txt on the host, demonstrating successful local remote code execution.

Impact Assessment & Supply Chain Vector

The impact of this command injection vulnerability is substantial due to its positioning in the software supply chain. While standard runtime vulnerabilities threaten the production environment, a synthesis-time vulnerability targets the development workstation and the deployment pipelines directly. An attacker who successfully exploits this flaw can execute arbitrary commands with the privileges of the active developer or the continuous integration (CI/CD) runner, gaining complete compromise over the underlying operating system environment.

In typical modern cloud deployments, developer machines and CI/CD pipelines hold highly sensitive credentials, such as active AWS session tokens, long-lived AWS IAM access keys, SSH keys, and access tokens for internal code repositories. Gaining execution on these runners allows an attacker to access environment variables, retrieve stored configuration secrets, and exfiltrate credentials to an external server. Because the execution runs within a trusted build phase, the outbound network requests generated by the payload might bypass egress firewall restrictions configured for production environments.

Additionally, access to the synthesis environment allows an attacker to manipulate the generated CloudFormation templates. This permits subtle modifications to infrastructure definitions, such as altering security group configurations to expose database ports, modifying IAM policy definitions to grant excessive permissions, or injecting malicious backdoors into the built Lambda deployment packages. The vulnerability therefore bridges local workstation compromise to complete cloud architecture compromise.

Remediation & Defense-in-Depth

The definitive mitigation for this vulnerability is upgrading the AWS CDK library to a patched version. For applications running on Linux or macOS workstations, upgrade aws-cdk-lib to version 2.245.0 or higher. For applications built on Windows systems, upgrade aws-cdk-lib to version 2.246.0 or higher to resolve compatibility issues with direct process spawning on Node.js v22+ environments.

In environments where upgrading the library is not immediately possible, organizations can enforce defensive controls to mitigate the risk. The vulnerability can be neutralized by forcing the use of Docker-based bundling rather than local bundling. This is achieved by ensuring that Docker is running and available to the CDK CLI, or by modifying the construct configuration to explicitly utilize containerized environments. When bundling runs inside an isolated Docker container, the command injection is constrained to the container workspace, preventing access to the host workstation's file system and environmental secrets.

Furthermore, organizations should restrict the permissions allocated to CI/CD runners during the synthesis phase. The generation of CloudFormation templates via cdk synth is a purely local compilation task that does not require direct access to active AWS credentials or cloud infrastructure endpoints. Separating the synthesis step into an isolated, unprivileged build phase that lacks cloud deployment credentials significantly limits the blast radius of a potential exploitation attempt. Implement static analysis and linting rules to flag or reject pull requests that modify bundling properties inside CDK infrastructure code.

Official Patches

AWSLocal bundling shell injection direct spawnSync fix
AWSWindows Node 22+ direct spawn compatibility and escaping fix

Technical Appendix

CVSS Score
7.3/ 10
CVSS:3.1/AV:L/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:H
EPSS Probability
0.66%
Top 54% most exploited

Affected Systems

AWS CDK (aws-cdk-lib)

Affected Versions Detail

Product
Affected Versions
Fixed Version
aws-cdk-lib
AWS
< 2.245.02.245.0
aws-cdk-lib (Windows)
AWS
< 2.246.02.246.0
AttributeDetail
CWE IDCWE-78
Attack VectorLocal
CVSS Score7.3 (CVSS:3.1)
EPSS Score0.00657 (Percentile: 46.42%)
ImpactUnauthenticated OS Command Execution
Exploit StatusProof of Concept / Public Exploit Code Available
CISA KEV StatusNot Listed

MITRE ATT&CK Mapping

T1059Command and Scripting Interpreter
Execution
CWE-78
Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')

The software constructs an OS command using externally-influenced input, but it does not neutralize or incorrectly neutralizes special elements that can modify the intended OS command when it is sent to a downstream component.

Known Exploits & Detection

GitHub (HeshamASH)Functional proof-of-concept demonstrating command injection via the externalModules property

Vulnerability Timeline

Pull Request #37292 submitted to fix local bundling shell injection via direct spawnSync.
2026-03-19
Pull Request #37412 submitted to resolve Windows Node 22+ direct spawn compatibility issues.
2026-03-30
Coordinated disclosure completed. CVE-2026-11417 and GHSA-999r-qq7v-r334 published.
2026-06-10
Public proof-of-concept repository released by external security researcher.
2026-06-10

References & Sources

  • [1]NVD CVE Entry
  • [2]AWS Security Bulletin
  • [3]GitHub Security Advisory
  • [4]AWS CDK Local Bundling Pull Request #37292
  • [5]AWS CDK Windows Process Spawning Pull Request #37412
  • [6]AWS CDK Release v2.245.0
  • [7]Public Proof of Concept Repository

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•23 minutes ago•CVE-2026-48748
7.5

CVE-2026-48748: Netty HTTP/3 QPACK Blocked Streams Memory Exhaustion

CVE-2026-48748 is a denial-of-service vulnerability in Netty's HTTP/3 codec (netty-codec-http3) occurring when QPACK dynamic tables are enabled but the blocked streams limit is not explicitly configured. A bug in limit checking and a memory leak in stream tracking allow unauthenticated remote attackers to exhaust the JVM heap memory and crash the server.

Amit Schendel
Amit Schendel
0 views•6 min read
•about 1 hour ago•CVE-2026-50009
4.8

CVE-2026-50009: Stateless Reset Token Exposure in Netty QUIC

CVE-2026-50009 is a cryptographic design vulnerability in the Netty network application framework. Prior to version 4.2.15.Final, the framework's QUIC protocol implementation fails to cryptographically segregate the generated Connection IDs and the associated Stateless Reset Tokens. An on-path network attacker who sniffs traffic during a Connection ID rotation can extract secret token material from cleartext headers, enabling them to inject spoofed reset packets and terminate active connections.

Alon Barad
Alon Barad
0 views•6 min read
•about 1 hour ago•CVE-2026-50010
7.5

CVE-2026-50010: Hostname Verification Bypass in Netty TLS Client

A critical hostname verification bypass vulnerability exists in the Netty network application framework when configured as a TLS client. When a developer registers a custom plain X509TrustManager, Netty wraps it inside an X509TrustManagerWrapper to adapt it to the X509ExtendedTrustManager API. However, this wrapper discards the SSLEngine context, bypassing critical hostname checks. Because the wrapper is identified as an X509ExtendedTrustManager, standard cryptographic engines and Netty's OpenSSL wrappers do not re-wrap it, failing to execute any hostname validation. Consequently, clients silently accept certificates for any host, enabling unauthenticated Man-in-the-Middle (MitM) attacks.

Amit Schendel
Amit Schendel
0 views•8 min read
•about 2 hours ago•CVE-2026-50011
7.5

CVE-2026-50011: Unbounded Resource Pre-Allocation in Netty Redis Codec

An uncontrolled resource pre-allocation flaw in the Netty Redis codec module allows remote unauthenticated attackers to cause a denial of service (OutOfMemoryError) by sending a crafted Redis Serialization Protocol (RESP) array header.

Amit Schendel
Amit Schendel
1 views•7 min read
•about 2 hours ago•CVE-2026-50020
5.3

CVE-2026-50020: HTTP Request Smuggling in Netty HttpObjectDecoder via Arbitrary Leading Control Bytes

CVE-2026-50020 is a medium-severity HTTP Request Smuggling/Response Smuggling vulnerability (CWE-444) within the Netty asynchronous network application framework. The flaw resides in Netty's HTTP codec implementation, specifically the HttpObjectDecoder class, which silently consumes arbitrary ISO control bytes preceding the first request line.

Alon Barad
Alon Barad
3 views•7 min read
•about 3 hours ago•CVE-2026-50560
6.9

CVE-2026-50560: Denial of Service in Netty HTTP/2 Codec via Max Header List Size Exception

CVE-2026-50560 describes a vulnerability in Netty's HTTP/2 codec implementation. When acting as an intermediary (such as a reverse proxy, API gateway, or edge server), Netty can be forced into an application-level Denial-of-Service condition. The attack is triggered by negotiating a restrictive SETTINGS_MAX_HEADER_LIST_SIZE from the client, causing Netty to process incoming requests fully, but subsequently crash or abort during outbound response serialization. This results in an asymmetrical consumption of resources on backend systems and thread starvation within the Netty event loop.

Alon Barad
Alon Barad
3 views•6 min read