CVE-2026-9277 shell-quote Command Injection: Affected Versions, Detection and the quote() Fix

June 12, 2026
June 12, 2026

0 min read

Vulnerabilities
CVE-2026-9277 shell-quote Command Injection

The shell-quote command injection flaw tracked as CVE-2026-9277 lets an attacker smuggle a second shell command past the library's own sanitization. The flaw affects shell-quote, an npm package downloaded over 214 million times per month, in every version from 1.1.0 through 1.8.3 and it is fixed in 1.8.4. This post covers what broke, how the injection executes, which versions are affected, what to hunt for, and why finding the vulnerable package is the easy part. Knowing whether it actually runs is the hard part.

The flaw carries CWE-77 (Improper Neutralization of Special Elements used in a Command) and CWE-78 (OS Command Injection). CVE-2026-9277 was reported by security researcher Akshat Sinha and fixed by maintainer Jordan Harband. The assigning CNA scored 8.1 (High) under CVSS 3.1 and 9.2 (Critical) under CVSS 4.0. NVD hasn’t yet published its own score.

Vulnerability Summary

FieldValue
CVE IDCVE-2026-9277
Affected packageshell-quote (npm)
Affected versions1.1.0 through 1.8.3
Fixed version1.8.4
CVSS 3.1 (CNA)8.1 HIGH, AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H
CVSS 4.0 (CNA)9.2 CRITICAL, AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
NVD/NIST base scoreNot yet assigned
EPSS0.00% (minimal exploitation likelihood)
WeaknessCWE-77, CWE-78
Monthly downloads214 million+
ReporterAkshat Sinha (@akshatgit)
Fix authorJordan Harband (@ljharb)
Patch commitljharb/shell-quote@1518179
PublishedMay 22, 2026

The High (3.1) versus Critical (4.0) split isn’t a contradiction. The CVSS 3.1 vector carries AC:H (high attack complexity) because exploitation requires the caller to feed an attacker-influenced object token into quote(). CVSS 4.0 models the same precondition as AT:P and still resolves to 9.2 Critical. With EPSS at 0.00% and no known public exploit, the urgency here is about reach, not active attacks in the wild. That distinction is the whole point of this writeup.

What Happened: The shell-quote Command Injection in quote()

A newline that should have been escaped wasn’t, and a function meant to be a shell-safety boundary handed a second command straight to the shell. The shell-quote command injection lives in quote(), not in the parser.

shell-quote provides two core functions: parse(), which turns shell command strings into token arrays, and quote(), which escapes strings for safe use in a shell. In vulnerable versions, quote() accepted object tokens (structured values representing shell operators) and sanitized the .op field by backslash-escaping characters one at a time with the regex /(.)/g. JavaScript's /(.)/g doesn’t match line terminator characters (\n, \r, U+2028, U+2029), so a newline inside .op passed through unescaped. POSIX shells read a literal newline as a command separator, so anything after it executes as a separate command, with no signal to the calling application.

How the Attack Chain Executes

Exploitation requires an attacker to influence the .op value of an object token that reaches quote(), after which any text following an injected newline runs as its own command. The behavior was confirmed under sh, bash, dash and zsh.

The vulnerable escaping logic

quote() escaped .op character by character with /(.)/g. Because that pattern doesn’t match line terminators in JavaScript, a \n, \r, U+2028, or U+2029 inside .op survived untouched and was written straight into the output string.

Why a newline becomes a second command

A literal newline is a command separator in POSIX shells. Once it reaches the shell unescaped, everything after it is parsed and run as a separate command. A minimal proof of concept:

const { parse, quote } = require('shell-quote');

// Direct construction
quote([{ op: ';\nid' }]);
// emits a literal newline; the second line executes as a command

// Via parse() with an envFn returning attacker-shaped objects
const tokens = parse('echo $X', () => ({ op: ';\nid' }));
require('child_process').execSync(quote(tokens), { shell: true });
// executes `id` after `echo`

Two reachable attack paths

Both entry points are documented API surface:

  1. Direct object token construction. An attacker who influences data passed to quote() supplies an object token with a malicious .op value containing \n, injecting commands directly into the output string.
  2. Environment function injection. When parse(cmd, envFn) is called with an envFn callback that returns object tokens, an attacker who controls the data source consulted by that callback can influence the .op value of the returned token, triggering the same injection indirectly.

Why This Matters: A Trust Boundary That Failed

When a function that exists to neutralize shell input stops neutralizing it, every caller that trusted its output inherits the flaw. That is what makes this npm supply chain vulnerability different from a routine bug.

shell-quote is used as a safety control. Applications pass user input through quote() specifically so the result is safe to hand to a shell. With over 214 million monthly downloads, it sits inside developer tooling, build systems, test runners, and shell wrappers across the ecosystem. Transitive dependency depth widens the exposure: many teams ship shell-quote without knowing it, because the vulnerable logic lives inside a dependency rather than in their own code. That last detail also explains why static analysis of the application layer doesn’t surface this. The flawed code isn’t in the application.

What Is Affected

Any code on shell-quote 1.1.0 through 1.8.3 that passes externally influenced data into quote(), or uses parse() with an envFn that returns attacker-influenced object tokens, is in scope, including transitive consumers. Specifically:

  • Node.js applications using quote() to sanitize shell arguments.
  • Applications using parse() with an envFn callback that returns attacker-influenced object tokens.
  • CI/CD pipelines, build tools, and developer tooling that construct shell commands from external input via shell-quote.
  • Downstream packages and frameworks that depend on shell-quote as a transitive dependency.

Teams that consume Node.js through a Linux distribution rather than installing shell-quote directly should also apply their vendor's update, since the fix reaches them through a repackaged nodejs rather than a direct dependency bump. SUSE, for example, tracks CVE-2026-9277 across its products and lists nodejs18, nodejs22 and nodejs24 as affected.

Indicators of Compromise and Behavioral Signals

There are no file hashes or network IOCs for a library logic flaw like this, so detection is behavioral. Hunt for unexpected shell processes spawned by Node.js and for command strings that contain embedded newlines.

CategoryWhat to look for
Versionsshell-quote 1.1.0 through 1.8.3 in any dependency tree.
ProcessNode.js processes spawning sh, bash, or cmd.exe with unexpected arguments.
ArgumentsCommand invocations containing multiline arguments or embedded \n / \r
NetworkAnomalous outbound connections from Node.js processes that handle external input.
CI/CDBuild or pipeline logs showing commands not present in the original workflow definition.

Immediate Response: The First-Hour Runbook

Patch first, then find every transitive instance, validate inputs as a stopgap, and check whether anomalous subprocesses already ran. The priority order is patch, inventory, contain, verify.

  1. Update immediately. Upgrade shell-quote to 1.8.4 across direct and transitive dependency trees. Run npm audit or yarn audit to identify affected instances.
  2. Audit dependency trees. Use npm ls shell-quote to find every installed copy in a project. Transitive depth matters.
  3. Validate object token inputs. Until patched, validate .op values against the expected parser operator allowlist before passing object tokens to quote().
  4. Monitor runtime behavior. Watch Node.js processes for anomalous subprocess spawning, particularly in services that accept external input and construct shell commands.
  5. Review CI/CD pipelines. Pipelines that use shell-quote in build scripts or test infrastructure are a priority remediation surface.
  6. Confirm prior exploitation. Review process and command-execution telemetry to determine whether anomalous subprocesses ran before the patch landed.

How the Fix Works in 1.8.4

The patch (commit ljharb/shell-quote@1518179) replaces per-character escaping with strict shape validation, which closes the reported vector and the adjacent ones at the same time. The object-token branch now enforces an allowlist:

  • { op }: the .op value must be a string from the exact operator set the parser emits (||, &&, ;;, |&, <(, <<<, >>, >&, <&, &, ;, (, ), |, <, >). Anything else throws a TypeError.
  • { op: 'glob', pattern }: pattern must be a string with no line terminators.
  • { comment }: comment must be a string with no line terminators.
  • Any other object shape throws a TypeError.

Since the fix uses an allowlist rather than a targeted regex tweak, it also proxies U+2028 and U+2029 separators in .op and line terminators in comments.

Why a Dependency Scan Finds the Package but Runtime Confirms the Risk

A dependency scanner tells you a vulnerable shell-quote is installed. That scanner can’t tell you whether quote() ever runs with attacker-influenced input. Severity without execution context is noise, and this CVE is a clean example: a High-to-Critical score sitting next to an EPSS of 0.00%.

That gap between presence and execution is where Kodem operates. 

  • Kodem’s SCA surfaces every vulnerable shell-quote across direct and transitive dependency trees, enriched with EPSS and exploit-maturity signals. 
  • Runtime Intelligence, Kodem's patented foundational layer, then confirms whether the package is actually loaded and whether the vulnerable quote() function is invoked at runtime. That is the difference between reachable and exploitable, and for this flaw it is the entire question. 
  • Kodem's Application Detection and Response layer, detects the anomalous subprocess execution that exploitation produces at the moment of exploit initiation, without relying on signatures. 
  • The Kodem Score folds CVSS, EPSS and runtime exposure into a single priority, so a vulnerable-but-never-invoked shell-quote doesn’t crowd out an issue that actually executes in production.

Hardening Your Pipeline Against the Next quote() Class Bug

Treat sanitization libraries as code that can fail, not as guarantees, and shrink the blast radius before the next escaping bypass surfaces.

  1. Pin and continuously monitor security-boundary dependencies, with alerts on new advisories for packages like shell-quote.
  2. Prefer argument-array process execution (execFile, spawn without a shell) over building shell strings wherever feasible.
  3. Validate and constrain any data that reaches command construction at the application layer, independent of the library.
  4. Maintain a current SBOM so transitive shell-quote instances are discoverable in minutes, not days.
  5. Add runtime detection for unexpected subprocess spawning from services that should never shell out.
  6. Gate CI/CD on dependency audits so vulnerable versions can’t re-enter the build.

What This npm Supply Chain Vulnerability Signals for the Ecosystem

The most disruptive npm flaws increasingly live inside the small, ubiquitous utilities that everything trusts and few audit. This is a vulnerability in a maintained package, distinct from malicious-package campaigns such as shai-hulud, but it lands the same way: deep in transitive trees, inside code the application layer can’t see.

  • Trust-boundary utilities are high-value because a single bypass invalidates assumptions across thousands of downstream callers.
  • Transitive depth hides blast radius, so inventory speed matters as much as patch speed.
  • Library logic flaws evade application-layer static analysis, which moves the useful question from "is the version present" to "did the vulnerable path execute."

A concrete prediction: over the next 12 months, expect more escaping-bypass and sanitization-logic CVEs in high-download utility packages, and expect detection to keep shifting from version presence toward runtime reachability. The teams that can answer "did quote() actually run with untrusted input" in minutes will spend far less of the next incident guessing.

Frequently Asked Questions

  1. What is CVE-2026-9277? It is a command injection vulnerability in the shell-quote npm package, caused by the quote() function failing to escape newline characters in object-token .op fields. An attacker who influences that value can inject a second shell command.
  2. Which versions of shell-quote are affected? All versions from 1.1.0 through 1.8.3. The fix is in 1.8.4.
  3. How do I know if my environment is exposed? Run npm ls shell-quote to find every direct and transitive copy, then check whether any service passes externally influenced data into quote() or uses parse() with an envFn fed by external sources.
  4. Am I at risk if shell-quote is only a transitive dependency? Potentially yes. The vulnerable code runs regardless of whether you installed it directly, so transitive consumers must upgrade too.
  5. How does the injection actually work? quote() escaped .op characters with the regex /(.)/g, which doesn’t match line terminators in JavaScript. An embedded newline passed through unescaped, and POSIX shells read it as a command separator.
  6. Can SCA or static analysis detect this? SCA detects the vulnerable version in your dependency tree, but static analysis of your application code will not reveal the flaw, because the vulnerable logic lives inside the library and only triggers at runtime. 
  7. Why does Kodem identify AI-related packages that may not appear in other SCA tools? Some SCA tools only surface AI-related packages for direct dependencies. Kodem classifies both direct and transitive dependencies, providing broader visibility into AI-related packages across the software supply chain and helping uncover packages that may otherwise be missed.
  8. What is the fastest way to stop exploitation before upgrading? Validate .op values against the expected parser operator allowlist before passing object tokens to quote(), and prefer non-shell process execution where possible.
  9. Is this being actively exploited? As of June 2026 there are no known public exploits, and EPSS estimates a 0.00% probability of near-term exploitation. The risk is driven by reach and the trust-boundary role, not by observed attacks.

The Bottom Line

Open source utilities are trusted because they are ubiquitous and maintained. That trust becomes a liability when a flaw lands inside a function an application relies on as a safety control. For many codebases shell-quote is exactly that control, so a bypass in quote() doesn’t add an attack path. The bypass removes a guarantee the calling code was built on.

The fix is straightforward: upgrade to 1.8.4. The harder problem is visibility. Knowing which services use shell-quote, whether they pass externally influenced input to quote(), and whether exploitation already happened is a runtime question, not a scanner question.

That is the part Kodem connects from code to runtime. Its SCA finds every vulnerable shell-quote in your dependency graph, Runtime Intelligence shows which services actually invoke quote(), and Kai turns that into a prioritized, ready-to-action fix. 

References

  1. GitHub Security Advisory GHSA-w7jw-789q-3m8p. https://github.com/ljharb/shell-quote/security/advisories/GHSA-w7jw-789q-3m8p
  2. Kodem Security. 4 November 2025. From Reachability to Reality: Proving Vulnerable Code was Executed & Exploited in Production. Kodem Security.
  3. Kodem Security. ‍Stop attacks at the first malicious action. Kodem Security
  4. Kodem Security. ‍Know which packages are actually exploitable, in your environment. Kodem Security
  5. NVD. 22 May 2026. CVE-2026-9277 Detail. NVD. https://nvd.nist.gov/vuln/detail/CVE-2026-9277
  6. OpenWall. 23 May 2026. OSS Security disclosure. OpenWall.
  7. Daily CyberSecurity. 28 June 2026. Popular npm Package shell-quote Patches Critical Command Injection Bug. Daily CyberSecurity
  8. shell-quote 1.8.4 patch commit. https://github.com/ljharb/shell-quote/commit/1518179
  9. Snyk. 22 May 2026. Arbitrary Command Injection in shell-quote. Snyk.
  10. Strobes. 10 June 2026. CVE-2026-9277. Strobes
  11. SUSE. CVE-2026-9277. 10 June 2026.  SUSE.
Table of contents

Related blogs

TanStack OpenAI Supply Chain Attack: Mini Shai-Hulud, IOCs, and First-Hour Response Runbook

The TanStack OpenAI supply chain attack delivered Mini Shai-Hulud through trusted npm publishing. Get the IOCs, affected packages, and first-hour runbook.

June 5, 2026

13

Inside the TeamPCP Supply Chain Campaign: From Trivy to LiteLLM to the Checkmarx Jenkins Plugin

TeamPCP backdoored the Checkmarx Jenkins AST plugin. Get the affected versions, IOCs, and the first-hour CI/CD supply chain runbook.

May 14, 2026

15

vm2 Sandbox Escape Vulnerabilities: The 2026 CVE Wave Turning AI Agents Into Host RCE Vectors

vm2 sandbox escape vulnerabilities now enable host-level RCE in AI agent frameworks. Get the affected CVEs, IOCs, and the first-hour response runbook.

May 14, 2026

10

Stop the waste.
Protect your environment with Kodem.

Get a personalized demo
Get a personalized demo

A Primer on Runtime Intelligence

See how Kodem's cutting-edge sensor technology revolutionizes application monitoring at the kernel level.

5.1k
Applications covered
1.1m
False positives eliminated
4.8k
Triage hours reduced

Platform Overview Video

Watch our short platform overview video to see how Kodem discovers real security risks in your code at runtime.

5.1k
Applications covered
1.1m
False positives eliminated
4.8k
Triage hours reduced

The State of the Application Security Workflow

This report aims to equip readers with actionable insights that can help future-proof their security programs. Kodem, the publisher of this report, purpose built a platform that bridges these gaps by unifying shift-left strategies with runtime monitoring and protection.

3D book mockup of Kodem's State of the Application Security Workflow 2025 report

Get real-time insights across the full stack…code, containers, OS, and memory

Watch how Kodem’s runtime security platform detects and blocks attacks before they cause damage. No guesswork. Just precise, automated protection.

Kodem issues list with a magnified view of insight icons: runtime, ingress, and exploitability
Combined author
Kodem Security Research Team
Publish date

0 min read

Vulnerabilities