GitHub Advisoryadvisory · PyPI

GHSA-j7qx-p75m-wp7g PraisonAI dynamic-context artifact tools read arbitrary host files outside artifact storage

HIGH Published 2026-06-18 Modified 2026-07-20 Official page ↗
Aliases
CVE-2026-56834
Ecosystem
PyPI
Packages
praisonai
Severity
High
CVSS vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N
Weaknesses
CWE-200, CWE-22
Reviewed
2026-06-18

Affected packages

• PyPI praisonai: >= 3.8.1, < 4.6.59 → fixed in 4.6.59

Description

PraisonAI dynamic-context artifact tools read arbitrary host files outside artifact storage Summary PraisonAI's Dynamic Context Discovery feature exposes artifact helper tools through `ctx.get_tools()`: ```python ctx = setup_dynamic_context() agent = Agent( instructions="You are a data analyst.", tools=ctx.get_tools(), hooks=[ctx.get_middleware()], ) ``` The official documentation describes these helpers as a way for the agent to explore large tool-output artifacts that were queued by the middleware: • large tool outputs are saved as artifacts; • the agent receives compact artifact references; and • the agent uses `artifact_tail` and `artifact_grep` to explore that data. The implemented artifact tools do not enforce that the supplied `artifact_path` is an artifact created by the configured store or that it lives under the configured artifact base directory. Instead, `artifact_head`, `artifact_tail`, `artifact_grep`, and `artifact_chunk` wrap the caller-supplied path directly into an `ArtifactRef` and then read it from the host filesystem. As a result, any prompt/user/tool-caller that can influence those tool arguments can read files readable by the PraisonAI process, such as project `.env` files, cloud credentials, SSH keys, source files, or other local data. Affected Product • Repository: `MervinPraison/PraisonAI` • Ecosystem: `pip` • Package: `praisonai` • Component: Dynamic Context Discovery artifact tools • Current source path: `src/praisonai/praisonai/context/queue.py` • Artifact store path: `src/praisonai/praisonai/context/artifact_store.py` • Latest PyPI version validated: `4.6.58` • Current `origin/main` validated: `1ad58ca02975ff1398efeda694ea2ab78f20cf3e` • Current `origin/main` tag validated: `v4.6.58` Suggested affected range: ```text pip:praisonai >= 3.8.1, str: ref = ArtifactRef(path=artifact_path, summary="", size_bytes=0) try: return artifact_store.head(ref, lines=lines) except FileNotFoundError: return f"Error: Artifact not found: {artifact_path}" ``` `artifact_tail()`, `artifact_grep()`, and `artifact_chunk()` have the same pattern. They trust the caller-supplied path rather than resolving it through an artifact identifier, store lookup, manifest, or base-directory containment check. The store methods then read that path directly: ```python def head(self, ref: ArtifactRef, lines: int = 50) -> str: file_path = Path(ref.path) if not file_path.exists(): raise FileNotFoundError(f"Artifact not found: {ref.path}") result_lines = [] with open(file_path, "r", encoding="utf-8", errors="replace") as f: ... ``` There is no check equivalent to: ```python resolved = Path(ref.path).resolve() base = self.base_dir.resolve() resolved.relative_to(base) ``` There is also no check that the file has a valid `.meta` sidecar or appears in `artifact_list()`. Local PoV Run against the latest PyPI package: ```bash uv run --with 'praisonai==4.6.58' \ python poc/pov_prai_cand_026_artifact_tools_arbitrary_file_read.py --json ``` The PoV: 1. Creates a temporary artifact base directory. 2. Creates a separate `outside-secret.txt` file outside that base directory. 3. Stores one legitimate artifact through `FileSystemArtifactStore.store()`. 4. Calls `artifact_head()` on the legitimate artifact as a positive control. 5. Calls `artifact_head()`, `artifact_grep()`, and `artifact_chunk()` on the outside file path. 6. Confirms `artifact_list()` does not list the outside file. Observed output summary from `evidence/pov-pypi-4.6.58.json`: ```json { "package": "praisonai", "package_version": "4.6.58", "controls": { "outside_file_not_listed": true, "outside_file_outside_base_dir": true, "valid_artifact_read_works": true }, "outside_head": "PRAI-CAND-026-OUTSIDE-ARTIFACT-SECRET", "outside_grep": "Found 1 matches:\\n\\n--- Line 1 ---\\n> PRAI-CAND-026-OUTSIDE-ARTIFACT-SECRET\\n second line", "outside_chunk": "PRAI-CAND-026-OUTSIDE-ARTIFACT-SECRET", "outside_file_listed_by_artifact_list": false, "vulnerable": true } ``` The PoV was rerun successfully after a fresh `origin/main` fetch; see `evidence/pov-pypi-4.6.58-rerun.json`. The PoV is local-only. It does not start a server, contact a third-party target, or use real credentials. Why This Is Not Intended Behavior This report does not claim that every file-reading tool is automatically a vulnerability. The issue is narrower: tools documented and named as artifact helpers accept arbitrary host file paths. The controls show the intended boundary: • a valid artifact stored under `base_dir` is readable; • an outside file is not returned by `artifact_list()`; • the outside file is outside `base_dir`; and • the read helpers still disclose the outside file when handed its absolute path. PraisonAI's own context-security documentation recommends relative paths and reviewing ignore rules to avoid sensitive-file exposure. Those controls are bypassed when artifact tools can be pointed directly at any readable host path. Impact If a PraisonAI application exposes an agent with `ctx.get_tools()` to untrusted or lower-trust prompts, the lower-trust caller can request artifact tools against arbitrary local paths. This can disclose sensitive host files readable by the PraisonAI process, including: • project `.env` files; • cloud or service credentials; • SSH keys; • local application configuration; • source files and private data; and • terminal/history artifacts from other runs if the path is known or guessed. The impact is confidentiality-only in the tested surface. Integrity and availability are not claimed for this report. Duplicate Posture I checked visible PraisonAI advisories and local prior PraisonAI submissions. This is distinct from nearby file-read/file-write issues: • `GHSA-9cr9-25q5-8prj` / `CVE-2026-47394` covers MCP CLI `workflow.show`, `workflow.validate`, and `deploy.validate` path handling. This report covers Dynamic Context Discovery artifact tools in `context/queue.py`. • `GHSA-hvhp-v2gc-268q` / `CVE-2026-47397` covers `write_file` arbitrary file write when `workspace=None`. This report is a read-only disclosure issue in artifact helper tools. • Public recipe registry path traversal advisories cover recipe publish/pull storage and extraction. This report does not involve the recipe registry. • Local prior submissions in this harness do not cover `artifact_head`, `artifact_tail`, `artifact_grep`, `artifact_chunk`, or `FileSystemArtifactStore` path containment. Severity Suggested severity: High. Suggested CVSS v3.1: Rationale: • `AV`: applies when an application exposes a PraisonAI agent over a network chat/API surface, which is a documented PraisonAI deployment pattern. • `AC`: no race, special environment, or complex path manipulation is required; an absolute readable path is sufficient. • `PR`: an unauthenticated or public-facing agent endpoint can be exploited without an account. Deployments that require authenticated chat/API access may score this as `PR:L`. • `UI`: the attacker directly supplies the prompt/tool argument to the exposed agent surface. • `C`: arbitrary readable host files can contain secrets or private data. • `I/A`: this report demonstrates read-only disclosure. Remediation Do not let artifact tools open arbitrary paths. Prefer stable artifact IDs over raw filesystem paths in tool …

Related

Alias · CVE (1)

  • CVE-2026-56834 PraisonAI is a multi-agent teams system. vulnerability

Weakness · CWE (2)

  • CWE-200 Exposure of Sensitive Information to an Unauthorized Actor weakness
  • CWE-22 Improper Limitation of a Pathname to a Restricted Directory weakness

References