Jun 9, 2026·6 min read·7 visits
An OS command injection vulnerability in shell-quote < 1.8.4 allows arbitrary command execution. The quote() function fails to escape line terminators within object-tokens due to a regular expression omission, enabling attackers to inject newlines that act as command separators in POSIX shells.
A technical breakdown of the OS command injection vulnerability in the shell-quote NPM package (CVE-2026-9277 / GHSA-w7jw-789q-3m8p). The bug resides in the character-by-character backslash-escaping logic applied to the .op field of object-tokens within the quote() function, which fails to match and escape line terminators due to a regex matching oversight in JavaScript. This allows unauthenticated remote attackers to execute arbitrary shell commands if they can control inputs processed by this library.
The NPM package shell-quote is designed to provide utility functions for parsing and quoting shell commands in Node.js environments. Its core functionality allows developers to safely serialize arrays of parameters into sanitized shell commands or parse complex terminal input strings into structured representation arrays. Because the library is frequently utilized prior to invoking shell executors such as child_process.exec or child_process.spawn, any failure to securely escape metacharacters can lead to command execution vulnerabilities.
CVE-2026-9277 (tracked as GHSA-w7jw-789q-3m8p) represents a critical command injection flaw identified within the quote() function. When serializing an array containing object-tokens (representing operators, globs, or comments), the library attempts to dynamically escape special characters. However, a regular expression matching defect allows line terminators to pass through unescaped.
The vulnerability exposes a broad attack surface in applications that pass structured or partially structured inputs to the command formatter. If an attacker can manipulate elements within the array passed to quote(), or inject values parsed during environment variable expansion in parse(), they can achieve arbitrary command execution under the context of the running application process.
The technical root cause of CVE-2026-9277 lies in the character-by-character backslash-escaping logic applied to the .op property of object-tokens. Within the quote() function, the library iterates over input array elements. If an element is identified as an object containing an .op field, the library attempts to escape each character of the operator string using the JavaScript regular expression arg.op.replace(/(.)/g, '\\$1').
In ECMAScript engines, the dot (.) character class matches any single character except line terminators. Because the dot-all (/s) modifier is absent in this pattern, the regular expression ignores the Carriage Return (\r, U+000D), Line Feed (\n, U+000A), Line Separator (U+2028), and Paragraph Separator (U+2029). As a result, the replacement expression \\$1 is never executed for these line terminators.
When the serialized output is constructed, these line terminators are written into the final string with zero escaping or sanitization. In POSIX-compliant shells (such as sh, bash, dash, or zsh), a literal newline is treated as an implicit command separator. When the shell interpreter parses the final string, it executes the commands sequentially, completely separating the original command context from the injected suffix commands.
The vulnerable code block inside quote() processes the token's operator as shown below:
// Vulnerable logic in shell-quote <= 1.8.3
if (arg && typeof arg === 'object') {
if (arg.op === 'glob') {
return arg.pattern;
}
// Character-by-character escape attempts using dot class
// This regex does not match line terminators (\n, \r)
return arg.op.replace(/(.)/g, '\\$1');
}An analysis of the fix implemented in commit 1518179 shows that the maintainers chose to eliminate the dynamic character-by-character escaping strategy entirely. Instead, they transitioned to strict schema and type validation for all object-tokens.
// Patched logic in shell-quote 1.8.4
// Rather than trying to escape free-form operators, shape validation is applied
if (arg && typeof arg === 'object') {
if (arg.op === 'glob') {
if (typeof arg.pattern !== 'string' || /[\r\n]/.test(arg.pattern)) {
throw new TypeError('glob pattern must be a string and cannot contain line terminators');
}
return arg.pattern;
}
if (typeof arg.op === 'string' && controlOperators.indexOf(arg.op) !== -1) {
return arg.op;
}
throw new TypeError('Invalid operator: ' + arg.op);
}The patch evaluates the object properties against structural limits. If an object is configured as a glob, the program checks for line terminators. If the object-token uses an operator, it must match one of the items inside controlOperators array (e.g. &&, ||, ;). Any input that deviates from this strict configuration raises a TypeError and halts the process.
Exploitation requires that an application exposes either the inputs of quote() or the custom environment variable expansion callback of parse() to attacker-controlled data. In a direct object injection scenario, the target application accepts JSON payloads and passes them to quote() without validation.
The diagram below models the sequence of execution leading to arbitrary command execution.
In secondary attack vectors, the application leverages parse(cmd, envFn). The envFn is a developer-supplied callback designed to resolve shell variables. If the callback resolves a variable to an object-token whose operator is sourced from external input, an injection occurs. For instance, if an HTTP header determines the value returned by envFn as { op: "&&\nid" }, the returned token is subsequently passed back to quote(), which fails to escape the newline.
POSIX shell engines interpret the unescaped newline as a command separator. While other characters within the payload such as i and d are escaped as \i\d, the shell strips these redundant backslashes, yielding the executable instruction id.
The impact of CVE-2026-9277 is categorized as high, with an assigned CVSS v3.1 base score of 8.1. An exploit allows an unauthenticated remote attacker to execute arbitrary OS commands within the context of the underlying Node.js application process. This can lead to complete compromise of the host system, horizontal privilege escalation, and lateral movement within the network.
Because the injected shell command executes with the permissions of the Node.js process, applications running as a high-privilege user or root are highly vulnerable. Attackers can leverage this access to extract environmental variables, read application source code, download malicious binaries, or establish persistent reverse shell connections.
The risk remains elevated for cloud-native configurations where environment variables often store database credentials, API keys, and cloud provider IAM metadata tokens. The lack of complex prerequisites other than exposing input serialization vectors makes applications processing multi-tenant structured configuration particularly susceptible.
The primary remediation is upgrading the shell-quote package dependency to version 1.8.4 or later. This can be accomplished by updating the dependency declaration within the project's package.json file and executing a package manager update cycle.
npm install shell-quote@1.8.4In environments where immediate dependency upgrades are blocked by legacy system constraints, teams must deploy input validation layers. Applications should enforce schema validation on all inputs parsed by, or passed to, the library. Ensuring that any array processed by quote() contains strictly string elements, or validating that any object-token lacks line terminators, effectively mitigates the vulnerability vector.
Additionally, developers should analyze any implementation of custom environment callbacks in parse(). Ensuring that the envFn only returns sanitized string values and never passes raw, unvalidated object-tokens prevents nested serialization exploitation paths.
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
shell-quote ljharb | >= 1.1.0, < 1.8.4 | 1.8.4 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-78 / CWE-77 |
| Attack Vector | Network (AV:N) |
| CVSS Severity | 8.1 (High) |
| EPSS Score | 0.00068 |
| Exploit Status | Proof of Concept |
| CISA KEV Status | Not Listed |
The software constructs an OS command using externally-influenced input, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command when it is sent to a downstream component.
CVE-2024-29203 identifies a cross-site scripting (XSS) vulnerability in the content ingestion and parsing mechanics of TinyMCE rich text editor. Due to a failure to enforce sandbox attributes on dynamic iframe elements and safely handle legacy embed objects, unauthenticated attackers can inject malicious elements that execute scripts within the context of the parent application session.
A high-severity memory corruption vulnerability exists in the V8 JavaScript engine of Google Chrome before versions 149.0.7827.102/103. The flaw arises from an incorrect bounds-check elimination during JIT compilation by the TurboFan optimizer, allowing remote attackers to achieve out-of-bounds read and write access inside the sandboxed renderer process.
An improper authentication vulnerability (CWE-287) exists in the legacy, deprecated Internet Key Exchange version 1 (IKEv1) key exchange protocol implementation in Check Point Security Gateways. The vulnerability is caused by a logic flow weakness during the certificate validation process for Remote Access VPN and Mobile Access (SSL VPN) connections. An unauthenticated remote attacker can exploit this weakness to bypass user authentication entirely, establishing a fully functional Remote Access VPN connection without a valid password.
GeoNode versions prior to 4.4.5 and 5.0.2 are vulnerable to Server-Side Request Forgery (SSRF) in the service registration endpoint. Authenticated attackers with low privileges can exploit insufficient input validation in the Web Map Service (WMS) registration module to force the application server to make outbound network queries to loopback addresses, private RFC1918 subnets, link-local scopes, and cloud metadata endpoints. This technical report details the mechanics of the vulnerability, the underlying architectural flaw, and how to effectively remediate and mitigate the associated security risks.
CVE-2022-0492 is a high-severity missing authorization vulnerability in the Linux kernel's Control Groups (cgroups) v1 implementation. The flaw resides within the cgroup_release_agent_write function in kernel/cgroup/cgroup-v1.c, where the kernel fails to validate if the process writing to the release_agent file possesses administrative capabilities in the initial user namespace. This allows a local attacker inside a container with root privileges (UID 0) to abuse user namespaces, mount a cgroups v1 directory, modify the release_agent parameter, and execute arbitrary commands on the host system as host root, effectively achieving a complete container escape.
NocoDB is subject to an insufficient session expiration vulnerability where OAuth access and refresh tokens are not invalidated or revoked during security-sensitive actions such as password changes, forgot-password requests, or password resets. This allows an attacker possessing an active OAuth token to maintain unauthorized persistence.