GitHub Advisoryadvisory · PyPI
GHSA-j7qx-p75m-wp7g PraisonAI dynamic-context artifact tools read arbitrary host files outside artifact storage
HIGH
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