Arbitrary Command Injection in strapi/strapi
Description
Arbitrary Command Injection in GitHub repository strapi/strapi prior to 4.1.0.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A command injection vulnerability in Strapi before 4.1.0 allows arbitrary command execution via unsanitized package name input to the CLI.
Vulnerability
An arbitrary command injection vulnerability exists in Strapi versions prior to 4.1.0. The flaw resides in the CLI helper functions getPackageInfo, getStarterPackageInfo, and downloadNpmStarter located in the file packages/strapi-generate-new/lib/utils/helpers.js. These functions used execa.command() with user-controlled package names, constructing shell commands without proper sanitization. The affected code path is reachable when a user runs Strapi's CLI commands that involve fetching or installing npm packages, such as npx create-strapi my-project --template @strapi/.... The issue was fixed in commit 2a3f5e988be6a2c7dae5ac22b9e86d579b462f4c which replaced execa.command() with execa() passing arguments as an array, preventing shell injection [1][2][3][4].
Exploitation
An attacker would need to convince a victim to run the Strapi CLI with a malicious package name as an argument. For example, constructing a template or plugin name that includes shell metacharacters. No authentication is required as the CLI runs directly in the user's shell. The attacker does not need any network position beyond the ability to communicate the malicious string (e.g., via social engineering or by hosting a malicious package). The concrete sequence is: the victim executes a Strapi CLI command (e.g., npx create-strapi my-project --template @attacker/malicious-name`), the CLI passes the attacker-controlled string to the vulnerable functions, the shell interprets the injected commands, and they run with the privileges of the victim user [3].
Impact
Successful exploitation allows an attacker to execute arbitrary commands on the victim's system with the same privileges as the user running the CLI. This can lead to full compromise of the development machine, including data theft, installation of malware, or lateral movement within the network. The impact is limited to users who run the CLI with a malicious package name, but it does not require authenticated access to a Strapi instance [2][3].
Mitigation
The vulnerability is fixed in Strapi version 4.1.0, released on 2022-02-28. Users should upgrade to 4.1.0 or later. There is no known workaround; users must avoid running the Strapi CLI with untrusted package names. The fix is available in the referenced commit and was incorporated into the 4.1.0 release [2][3].
- GitHub - strapi/strapi: 🚀 Strapi is the leading open-source headless CMS. It’s 100% JavaScript/TypeScript, fully customizable, and developer-first.
- NVD - CVE-2022-0764
- Merge pull request #12649 from strapi/cli-security · strapi/strapi@2a3f5e9
- Merge pull request #12649 from strapi/cli-security · strapi/strapi@2a3f5e9
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
strapinpm | < 4.1.0 | 4.1.0 |
Affected products
2- strapi/strapi/strapiv5Range: unspecified
Patches
12a3f5e988be6Merge pull request #12649 from strapi/cli-security
2 files changed · +6 −6
packages/cli/create-strapi-starter/utils/fetch-npm-starter.js+4 −4 modified@@ -15,7 +15,7 @@ const stopProcess = require('./stop-process'); async function getPackageInfo(packageName, { useYarn } = {}) { // Use yarn if possible because it's faster if (useYarn) { - const { stdout } = await execa.command(`yarn info ${packageName} --json`); + const { stdout } = await execa('yarn', ['info', packageName, '--json']); const yarnInfo = JSON.parse(stdout); return { name: yarnInfo.data.name, @@ -24,7 +24,7 @@ async function getPackageInfo(packageName, { useYarn } = {}) { } // Fallback to npm - const { stdout } = await execa.command(`npm view ${packageName} name version --silent`); + const { stdout } = await execa('npm', ['view', packageName, 'name', 'version', '--silent']); // Use regex to parse name and version from CLI result const [name, version] = stdout.match(/(?<=')(.*?)(?=')/gm); return { name, version }; @@ -67,11 +67,11 @@ async function getStarterPackageInfo(starter, { useYarn } = {}) { async function downloadNpmStarter({ name, version }, parentDir, { useYarn } = {}) { // Download from npm, using yarn if possible if (useYarn) { - await execa.command(`yarn add ${name}@${version} --no-lockfile --silent`, { + await execa('yarn', ['add', `${name}@${version}`, '--no-lockfile', '--silent'], { cwd: parentDir, }); } else { - await execa.command(`npm install ${name}@${version} --no-save --silent`, { + await execa('npm', ['install', `${name}@${version}`, '--no-save', '--silent'], { cwd: parentDir, }); }
packages/generators/app/lib/utils/fetch-npm-template.js+2 −2 modified@@ -10,7 +10,7 @@ const chalk = require('chalk'); * @returns {Object} */ async function getPackageInfo(packageName) { - const { stdout } = await execa.shell(`npm view ${packageName} name version --silent`); + const { stdout } = await execa('npm', ['view', packageName, 'name', 'version', '--silent']); // Use regex to parse name and version from CLI result const [name, version] = stdout.match(/(?<=')(.*?)(?=')/gm); return { name, version }; @@ -46,7 +46,7 @@ async function getTemplatePackageInfo(template) { */ async function downloadNpmTemplate({ name, version }, parentDir) { // Download from npm - await execa.shell(`npm install ${name}@${version} --no-save --silent`, { + await execa('npm', ['install', `${name}@${version}`, '--no-save', '--silent'], { cwd: parentDir, });
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
7- github.com/advisories/GHSA-xrjf-phvv-r4vrghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2022-0764ghsaADVISORY
- github.com/strapi/strapi/blob/master/packages/generators/app/lib/utils/fetch-npm-template.jsghsaWEB
- github.com/strapi/strapi/commit/2a3f5e988be6a2c7dae5ac22b9e86d579b462f4cghsax_refsource_MISCWEB
- github.com/strapi/strapi/issues/12879ghsax_refsource_MISCWEB
- huntr.dev/bounties/001d1c29-805a-4035-93bb-71a0e81da3e5ghsax_refsource_CONFIRMWEB
- www.github.com/strapi/strapi/commit/2a3f5e988be6a2c7dae5ac22b9e86d579b462f4cghsaWEB
News mentions
0No linked articles in our index yet.