CSIRTS // UNIFIED SECURITY ADVISORY FEEDSYS ● ONLINE · POWERED BY INTELFUSIONS.COM

GHSA-5jv7-2mjm-h6qj: npm PraisonAI utility shell safe-command wrapper allowlist bypass via shell chaining

highCVSS 8.8CVE-2026-57133
Summary The published npm package praisonai ships dist/tools/utility-tools.js, which exports a shell(command) helper described in source as: Execute shell command (safe version - read-only commands) The helper attempts to enforce a safe read-only command allowlist by checking only the first whitespace-delimited token: const safeCommands = ['ls', 'cat', 'head', 'tail', 'wc', 'grep', 'find', 'echo', 'date', 'pwd', 'which']; const firstWord = command.split(/\s+/)[0]; if (!safeCommands.includes(firstWord)) { return { success: false, error: Command not allowed: ${firstWord} }; } It then passes the entire original string to Node child_process.exec(): const { stdout, stderr } = await execAsync(command, { timeout: 5000 }); Because exec() runs the command through a shell, a command string that starts with an allowed command can append a second non-allowlisted command with shell metacharacters. For example, direct printf <marker> is rejected, but echo ok; printf <marker> is accepted and executes printf. This bypasses the helper's safe-command policy and allows arbitrary shell commands to run with the PraisonAI process privileges when an application, agent, or integration exposes this helper to lower-trust users, prompts, model output, or plugin/tool input. The PoV is deterministic and local-only. It installs only the npm package, runs harmless marker commands, and does not contact any live service after installation. Technical Details utility-tools.shell() authorizes one token but executes the full shell string. Source-head implementation: export async function shell(command: string): Promise<ToolResult<string>> { // Only allow safe read-only commands const safeCommands = ['ls', 'cat', 'head', 'tail', 'wc', 'grep', 'find', 'echo', 'date', 'pwd', 'which']; const firstWord = command.split(/\s+/)[0]; if (!safeCommands.includes(firstWord)) { return { success: false, error: Command not allowed: ${firstWord} }; } try { const { exec } = await import('child_process');

Details

Source
GitHub Security Advisories (INTL · database · site)
Severity
high — CVSS 8.8
Published
2026-06-18
Last updated
2026-07-20
Exploitation
Not in CISA KEV at last sync

Original advisory: https://github.com/advisories/GHSA-5jv7-2mjm-h6qj

Referenced CVEs

CVECSIRTS overviewExternal
CVE-2026-57133coverage & exploitation statusNVD · CVE.org

More from GitHub Security Advisories