npm PraisonAI utility shell safe-command wrapper allowlist bypass via shell chaining
Date: 2026-06
Affected: npm/praisonai
Attack vector: other
Category: vulnerability-disclosure
Severity: High
CWE: CWE-693
CWE-78
CWE-863
CVSS: 8.8 (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H)

## Summary The published npm package `praisonai` ships `dist/tools/utility-tools.js`, which exports a `shell(command)` helper described in source as: ```text 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: ```ts 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()`: ```ts 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. #


Mitigations:

Architectural layers (MAESTRO):