CVE-2026-57133: Praisonai Npm PraisonAI Utility Shell Safe-command Vulnerability

HIGH
Advisory Identifier: GHSA-5jv7-2mjm-h6qj
CVSS 8.8
CWE-78 CWE-693 CWE-863
Published
Advisory Summary

CVE-2026-57133 is a HIGH (CVSS 8.8) npm praisonai utility shell safe-command vulnerability (CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')) affecting Praisonai libraries in the npm ecosystem. The issue involves npm praisonai utility shell safe-command wrapper allowlist bypass via shell chaining. Remediation is available by upgrading affected packages to version 1.7.2.

CVE-2026-57133 at a Glance

CVE Identifier CVE-2026-57133
GHSA Identifier GHSA-5jv7-2mjm-h6qj
Severity HIGH
CVSS v3.1 Base Score 8.8
CWE Classification CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
Affected Product Praisonai
Package Ecosystem npm
Published Date
Last Updated

Security Impact

CVSS: 8.8

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H).

Attack Vector Network (AV:N)
Attack Complexity Low (AC:L)
Privileges Required Low (PR:L)
User Interaction None (UI:N)
Scope Unchanged (S:U)
Confidentiality High (C:H)
Integrity High (I:H)
Availability High (A:H)

How to Fix CVE-2026-57133

To remediate this vulnerability, upgrade all affected Praisonai dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

praisonai fixed: 1.7.2
npm install praisonai@1.7.2
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

npm ls praisonai

How to Check if You Are Affected

To determine whether your Node.js application is affected by CVE-2026-57133, inspect your project dependencies using npm:

npm ls praisonai

Analyze the terminal output to locate any version of Praisonai in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 1.7.2), your application is affected.

Note: The npm ls praisonai command inspects dependencies declared in your package.json and lockfile; it does not perform automated runtime dynamic scanning.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection'), where the product constructs all or part of an os command using externally-influenced input from an upstream component, 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. In Praisonai, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

## 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. ## Technical Details `utility-tools.shell()` authorizes one token but executes the full shell string. Source-head implementation: ```ts 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'); const { promisify } = await import('util'); const execAsync = promisify(exec); const { stdout, stderr } = await execAsync(command, { timeout: 5000 }); return { success: true, data: stdout || stderr }; } catch (error: any) { return { success: false, error: error.message ?? String(error) }; } } ``` The published `npm:praisonai@1.7.1` dist file preserves the same behavior: - `exports.shell = shell` - `const firstWord = command.split(/\s+/)[0]` - `if (!safeCommands.includes(firstWord)) ...` - `const { stdout, stderr } = await execAsync(command, { timeout: 5000 })` This creates a policy/parser differential: PraisonAI checks only the first token, while the shell parses the full string as a script. ### Why This Is Not Intended Behavior The helper is explicitly documented in code as a "safe version" for read-only commands and contains an allowlist of specific safe commands. The control test proves that non-allowlisted commands are intended to be blocked: direct `printf <marker>` returns `Command not allowed: printf`. The same helper accepting `echo ok; printf <marker>` is therefore a bypass of the intended safe-command boundary, not merely a permissive command runner. This is also consistent with Node's own guidance for shell execution: `child_process.exec()` runs through a shell, and shell metacharacters can change which commands execute. The fix should make PraisonAI's authorization boundary match what is actually executed. ## PoV Run from a local reproduction checkout: ```bash node poc/pov_poc.js 1.7.1 ``` Observed output summary from `evidence/pov-npm-1.7.1.json`: ```json { "package": "npm:praisonai", "version": "1.7.1", "installedPackageVersion": "1.7.1", "commands": { "directDisallowedCommand": "printf poc.7.1", "benignAllowedCommand": "echo poc", "chainedBypassCommand": "echo poc; printf poc.7.1" }, "controls": { "directDisallowedRejected": true, "benignAllowedAccepted": true, "patchedControlRejectsChainedShell": true }, "observed": { "directDisallowed": { "success": false, "error": "Command not allowed: printf" }, "chainedBypass": { "success": true, "data": "poc\npoc.7.1" } }, "vulnerable": true } ``` Interpretation: - Direct `printf <marker>` is rejected because `printf` is not in `safeCommands`. - Benign `echo ...` is accepted. - `echo ...; printf <marker>` is accepted because the first token is `echo`. - The shell then executes the non-allowlisted `printf` command. - A patched-control validator that rejects shell metacharacters before execution blocks the chained command while still allowing benign `echo`. The PoV uses only harmless marker output. It does not read system files, leak environment variables, call external services, or run destructive commands. ## PoC The PoV section above contains the local reproduction command, input, and decisive output. ## Impact If lower-trust users, prompts, model output, plugins, or tool input can influence a command string passed to `utility-tools.shell()`, the safe-command allowlist does not restrict execution to the intended read-only commands. An attacker can append arbitrary shell commands after an allowed first token and run them with the PraisonAI process privileges. Concrete consequences depend on the embedding application and process privileges, but can include: - reading files and secrets available to the process; - modifying files or project state; - invoking local tools and package managers; - network exfiltration if the host permits egress; and - denial of service by running expensive commands. This report does not claim that npm PraisonAI exposes this helper as a default unauthenticated network service. It is a library-level safe-command wrapper bypass in a shipped npm subpath. ### Severity Suggested severity: High. Rationale: - `AV`: common PraisonAI use is a network-facing application, agent API, or tool integration that accepts user or prompt-controlled tasks. - `AC`: a single command string beginning with an allowed command is sufficient. - `PR`: conservative scoring assumes the attacker can submit prompts or work items to the application using this helper. - `UI`: no further operator interaction is required once the command reaches the helper. - `S`: impact is within the PraisonAI-hosting process and its host context. - `C/I/A`: arbitrary shell commands can affect confidentiality, integrity, and availability depending on process privileges. If maintainers score only direct local library use, `AV:L` may be reasonable. If a deployment exposes this helper through unauthenticated agent/tool endpoints, `PR:N` may be reasonable. ## Suggested Fix Avoid passing policy-checked strings to a shell. Recommended: 1. Replace `exec(command)` with `execFile()` or `spawn(command, args, { shell: false })`. 2. Require callers to pass `{ command, args }` instead of a shell string, or parse the shell string into argv with a shell-aware parser before policy checks. 3. Apply the allowlist to the exact executable that will be invoked. 4. Reject shell metacharacters (`;`, `&&`, `||`, `|`, backticks, `$()`, redirects, newlines) if a string API must remain available. 5. Add regression tests proving that `echo ok` is allowed while `printf marker`, `echo ok; printf marker`, `echo ok && printf marker`, and `echo ok | printf marker` are rejected. If this helper is not intended to be public, also consider adding a package `exports` map that exposes only supported public API paths. ## Affected Package/Versions - Repository: `MervinPraison/PraisonAI` - Ecosystem: `npm` - Package: `praisonai` - Component: TypeScript utility tools helper `src/praisonai-ts/src/tools/utility-tools.ts` - Published dist path: `node_modules/praisonai/dist/tools/utility-tools.js` - Latest npm package validated: `1.7.1` - Current `origin/main` validated: `1ad58ca02975ff1398efeda694ea2ab78f20cf3e` - `src/praisonai-ts/package.json` at `origin/main`: `praisonai` `1.7.1` Suggested affected range: ```text npm:praisonai >= 1.5.1, <= 1.7.1 ``` All published npm `1.x` versions were swept locally: - `1.0.0` through `1.5.0`: `dist/tools/utility-tools.js` was not present in the tested package. - `1.5.1`, `1.5.2`, `1.5.3`, `1.5.4`, `1.6.0`, `1.7.0`, and `1.7.1`: vulnerable. The npm package has no `exports` map and ships `dist` in its `files` list, so the affected helper is importable as a package subpath: ```js const { shell } = require("praisonai/dist/tools/utility-tools.js"); ``` The root package entry point does not appear to re-export this helper directly. This report is scoped to the shipped npm subpath and the TypeScript source that generates it. ## Advisory History Visible PraisonAI advisories and prior submissions were checked. The closest known issues are adjacent but distinct: - `GHSA-vjv9-7m7j-h833` covers npm TypeScript `SandboxExecutor.allowedCommands` in `src/cli/features/sandbox-executor.ts`, where a caller-supplied allowlist is checked before `spawn("sh", ["-c", command])`. - This report covers npm TypeScript `utility-tools.shell()` in `src/tools/utility-tools.ts`, where a built-in "safe read-only commands" allowlist is checked before `child_process.exec(command)`. - Fixing only `SandboxExecutor` leaves this helper unchanged. - The public Python/PyPI command-injection advisories cover different packages, files, and execution paths, such as Python `execute_command`, `run_python()`, memory hooks, and subprocess sandbox code. This is a sibling-callsite variant of the same mature allowlist/shell-parser class, but it is not the same function, policy surface, affected version range, or shipped import path as the prior npm `SandboxExecutor` advisory.

CVE-2026-57133 Affected Praisonai Versions

1 component(s)
Fixed Versions:
1.7.2
Product / Package Ecosystem Affected Versions Fixed Version
praisonai
npm
≥ 1.5.1
< 1.7.2
1.7.2

References

Frequently Asked Questions

What is CVE-2026-57133?
CVE-2026-57133 is a security vulnerability in Praisonai involving npm PraisonAI utility shell safe-command wrapper allowlist bypass via shell chaining under CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
Which Praisonai versions are affected?
Affected versions include releases prior to 1.7.2 across affected packages: praisonai.
What version fixes CVE-2026-57133?
Upgrading to 1.7.2 (or the latest patched release for your respective branch) resolves the vulnerability.
Is praisonai affected?
Yes, praisonai is affected in releases prior to 1.7.2. Upgrade your dependency to 1.7.2 or later.
What is the CVSS score of CVE-2026-57133?
CVE-2026-57133 has a CVSS v3.1 base score of 8.8 (HIGH) with vector string CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H.
What CWE is associated with CVE-2026-57133?
CVE-2026-57133 is classified under CWE-78: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') (The product constructs all or part of an OS command using externally-influenced input from an upstream component, 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.).
How can I check npm dependencies for CVE-2026-57133?
Run the dependency tree command: 'npm ls praisonai'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-5jv7-2mjm-h6qj",
  "modified" : "2026-07-20T21:28:11Z",
  "published" : "2026-06-18T14:26:54Z",
  "aliases" : [ "CVE-2026-57133" ],
  "summary" : "npm PraisonAI utility shell safe-command wrapper allowlist bypass via shell chaining",
  "details" : "## Summary\n\nThe published npm package `praisonai` ships `dist/tools/utility-tools.js`, which exports a `shell(command)` helper described in source as:\n\n```text\nExecute shell command (safe version - read-only commands)\n```\n\nThe helper attempts to enforce a safe read-only command allowlist by checking only the first whitespace-delimited token:\n\n```ts\nconst safeCommands = ['ls', 'cat', 'head', 'tail', 'wc', 'grep', 'find', 'echo', 'date', 'pwd', 'which'];\nconst firstWord = command.split(/\\s+/)[0];\n\nif (!safeCommands.includes(firstWord)) {\n    return { success: false, error: `Command not allowed: ${firstWord}` };\n}\n```\n\nIt then passes the entire original string to Node `child_process.exec()`:\n\n```ts\nconst { stdout, stderr } = await execAsync(command, { timeout: 5000 });\n```\n\nBecause `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`.\n\nThis 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.\n\nThe 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.\n\n## Technical Details\n\n`utility-tools.shell()` authorizes one token but executes the full shell string.\n\nSource-head implementation:\n\n```ts\nexport async function shell(command: string): Promise<ToolResult<string>> {\n    // Only allow safe read-only commands\n    const safeCommands = ['ls', 'cat', 'head', 'tail', 'wc', 'grep', 'find', 'echo', 'date', 'pwd', 'which'];\n    const firstWord = command.split(/\\s+/)[0];\n\n    if (!safeCommands.includes(firstWord)) {\n        return { success: false, error: `Command not allowed: ${firstWord}` };\n    }\n\n    try {\n        const { exec } = await import('child_process');\n        const { promisify } = await import('util');\n        const execAsync = promisify(exec);\n\n        const { stdout, stderr } = await execAsync(command, { timeout: 5000 });\n        return { success: true, data: stdout || stderr };\n    } catch (error: any) {\n        return { success: false, error: error.message ?? String(error) };\n    }\n}\n```\n\nThe published `npm:praisonai@1.7.1` dist file preserves the same behavior:\n\n- `exports.shell = shell`\n- `const firstWord = command.split(/\\s+/)[0]`\n- `if (!safeCommands.includes(firstWord)) ...`\n- `const { stdout, stderr } = await execAsync(command, { timeout: 5000 })`\n\nThis creates a policy/parser differential: PraisonAI checks only the first token, while the shell parses the full string as a script.\n\n### Why This Is Not Intended Behavior\n\nThe helper is explicitly documented in code as a \"safe version\" for read-only commands and contains an allowlist of specific safe commands. The control test proves that non-allowlisted commands are intended to be blocked: direct `printf <marker>` returns `Command not allowed: printf`.\n\nThe same helper accepting `echo ok; printf <marker>` is therefore a bypass of the intended safe-command boundary, not merely a permissive command runner.\n\nThis is also consistent with Node's own guidance for shell execution: `child_process.exec()` runs through a shell, and shell metacharacters can change which commands execute. The fix should make PraisonAI's authorization boundary match what is actually executed.\n\n## PoV\n\nRun from a local reproduction checkout:\n\n```bash\nnode poc/pov_poc.js 1.7.1\n```\n\nObserved output summary from `evidence/pov-npm-1.7.1.json`:\n\n```json\n{\n  \"package\": \"npm:praisonai\",\n  \"version\": \"1.7.1\",\n  \"installedPackageVersion\": \"1.7.1\",\n  \"commands\": {\n    \"directDisallowedCommand\": \"printf poc.7.1\",\n    \"benignAllowedCommand\": \"echo poc\",\n    \"chainedBypassCommand\": \"echo poc; printf poc.7.1\"\n  },\n  \"controls\": {\n    \"directDisallowedRejected\": true,\n    \"benignAllowedAccepted\": true,\n    \"patchedControlRejectsChainedShell\": true\n  },\n  \"observed\": {\n    \"directDisallowed\": {\n      \"success\": false,\n      \"error\": \"Command not allowed: printf\"\n    },\n    \"chainedBypass\": {\n      \"success\": true,\n      \"data\": \"poc\\npoc.7.1\"\n    }\n  },\n  \"vulnerable\": true\n}\n```\n\nInterpretation:\n\n- Direct `printf <marker>` is rejected because `printf` is not in `safeCommands`.\n- Benign `echo ...` is accepted.\n- `echo ...; printf <marker>` is accepted because the first token is `echo`.\n- The shell then executes the non-allowlisted `printf` command.\n- A patched-control validator that rejects shell metacharacters before execution blocks the chained command while still allowing benign `echo`.\n\nThe PoV uses only harmless marker output. It does not read system files, leak environment variables, call external services, or run destructive commands.\n\n## PoC\n\nThe PoV section above contains the local reproduction command, input, and decisive output.\n\n## Impact\n\nIf lower-trust users, prompts, model output, plugins, or tool input can influence a command string passed to `utility-tools.shell()`, the safe-command allowlist does not restrict execution to the intended read-only commands. An attacker can append arbitrary shell commands after an allowed first token and run them with the PraisonAI process privileges.\n\nConcrete consequences depend on the embedding application and process privileges, but can include:\n\n- reading files and secrets available to the process;\n- modifying files or project state;\n- invoking local tools and package managers;\n- network exfiltration if the host permits egress; and\n- denial of service by running expensive commands.\n\nThis report does not claim that npm PraisonAI exposes this helper as a default unauthenticated network service. It is a library-level safe-command wrapper bypass in a shipped npm subpath.\n\n### Severity\n\nSuggested severity: High.\n\nRationale:\n\n- `AV`: common PraisonAI use is a network-facing application, agent API, or tool integration that accepts user or prompt-controlled tasks.\n- `AC`: a single command string beginning with an allowed command is sufficient.\n- `PR`: conservative scoring assumes the attacker can submit prompts or work items to the application using this helper.\n- `UI`: no further operator interaction is required once the command reaches the helper.\n- `S`: impact is within the PraisonAI-hosting process and its host context.\n- `C/I/A`: arbitrary shell commands can affect confidentiality, integrity, and availability depending on process privileges.\n\nIf maintainers score only direct local library use, `AV:L` may be reasonable. If a deployment exposes this helper through unauthenticated agent/tool endpoints, `PR:N` may be reasonable.\n\n## Suggested Fix\n\nAvoid passing policy-checked strings to a shell.\n\nRecommended:\n\n1. Replace `exec(command)` with `execFile()` or `spawn(command, args, { shell: false })`.\n2. Require callers to pass `{ command, args }` instead of a shell string, or parse the shell string into argv with a shell-aware parser before policy checks.\n3. Apply the allowlist to the exact executable that will be invoked.\n4. Reject shell metacharacters (`;`, `&&`, `||`, `|`, backticks, `$()`, redirects, newlines) if a string API must remain available.\n5. Add regression tests proving that `echo ok` is allowed while `printf marker`, `echo ok; printf marker`, `echo ok && printf marker`, and `echo ok | printf marker` are rejected.\n\nIf this helper is not intended to be public, also consider adding a package `exports` map that exposes only supported public API paths.\n\n## Affected Package/Versions\n\n- Repository: `MervinPraison/PraisonAI`\n- Ecosystem: `npm`\n- Package: `praisonai`\n- Component: TypeScript utility tools helper `src/praisonai-ts/src/tools/utility-tools.ts`\n- Published dist path: `node_modules/praisonai/dist/tools/utility-tools.js`\n- Latest npm package validated: `1.7.1`\n- Current `origin/main` validated: `1ad58ca02975ff1398efeda694ea2ab78f20cf3e`\n- `src/praisonai-ts/package.json` at `origin/main`: `praisonai` `1.7.1`\n\nSuggested affected range:\n\n```text\nnpm:praisonai >= 1.5.1, <= 1.7.1\n```\n\nAll published npm `1.x` versions were swept locally:\n\n- `1.0.0` through `1.5.0`: `dist/tools/utility-tools.js` was not present in the tested package.\n- `1.5.1`, `1.5.2`, `1.5.3`, `1.5.4`, `1.6.0`, `1.7.0`, and `1.7.1`: vulnerable.\n\nThe npm package has no `exports` map and ships `dist` in its `files` list, so the affected helper is importable as a package subpath:\n\n```js\nconst { shell } = require(\"praisonai/dist/tools/utility-tools.js\");\n```\n\nThe root package entry point does not appear to re-export this helper directly. This report is scoped to the shipped npm subpath and the TypeScript source that generates it.\n\n## Advisory History\n\nVisible PraisonAI advisories and prior submissions were checked. The closest known issues are adjacent but distinct:\n\n- `GHSA-vjv9-7m7j-h833` covers npm TypeScript `SandboxExecutor.allowedCommands` in `src/cli/features/sandbox-executor.ts`, where a caller-supplied allowlist is checked before `spawn(\"sh\", [\"-c\", command])`.\n- This report covers npm TypeScript `utility-tools.shell()` in `src/tools/utility-tools.ts`, where a built-in \"safe read-only commands\" allowlist is checked before `child_process.exec(command)`.\n- Fixing only `SandboxExecutor` leaves this helper unchanged.\n- The public Python/PyPI command-injection advisories cover different packages, files, and execution paths, such as Python `execute_command`, `run_python()`, memory hooks, and subprocess sandbox code.\n\nThis is a sibling-callsite variant of the same mature allowlist/shell-parser class, but it is not the same function, policy surface, affected version range, or shipped import path as the prior npm `SandboxExecutor` advisory.",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "npm",
      "name" : "praisonai"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "1.5.1"
      }, {
        "fixed" : "1.7.2"
      } ]
    } ],
    "database_specific" : {
      "last_known_affected_version_range" : "<= 1.7.1"
    }
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-5jv7-2mjm-h6qj"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/MervinPraison/PraisonAI"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-693", "CWE-78", "CWE-863" ],
    "severity" : "HIGH",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-06-18T14:26:54Z",
    "nvd_published_at" : null
  }
}