GHSA-j7qx-p75m-wp7g: PraisonAI dynamic-context artifact tools read arbitrary host files outside artifact storage
PraisonAI dynamic-context artifact tools read arbitrary host files outside artifact storageSummaryPraisonAI's Dynamic Context Discovery feature exposes artifact helper tools
through `ctx.get_tools()`: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; andthe 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 ProductRepository: `MervinPraison/PraisonAI`Ecosystem: `pip`Package: `praisonai`Component: Dynamic Context Discovery artifact toolsCurrent 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:Representative local sweep:`3.8.1`: vulnerable`4.0.0`: vulnerable`4.5.113`: vulnerable`4.6.33`: vulnerable`4.6.34`: vulnerable`4.6.40`: vulnerable`4.6.50`: vulnerable`4.6.58`: vulnerableRoot Cause`create_artifact_tools()` creates an artifact store bound to `base_dir`, but the
read tools do not use `base_dir` for containment.For example, `artifact_head()` accepts `artifact_path` and immediately creates
an `ArtifactRef` with that 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:There is no check equivalent to:There is also no check that the file has a valid `.meta` sidecar or appears in
`artifact_list()`.Local PoVRun against the latest PyPI package:The PoV:Creates a temporary artifact base directory.Creates a separate `outside-secret.txt` file outside that base directory.Stores one legitimate artifact through `FileSystemArtifactStore.store()`.Calls `artifact_head()` on the legitimate artifact as a positive control.Calls `artifact_head()`, `artifact_grep()`, and `artifact_chunk()` on the
outside file path.Confirms `artifact_list()` does not list the outside file.Observed output summary from `evidence/pov-pypi-4.6.58.json`: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 BehaviorThis 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`; andthe 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.ImpactIf 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; andterminal/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 PostureI 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.SeveritySuggested 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.RemediationDo not let artifact tools open arbitrary paths. Prefer stable artifact IDs over
raw filesystem paths in tool arguments.Recommended fixes:Change tool schemas to accept `artifact_id` plus optional `run_id` and
`agent_id`, then resolve those through the artifact store's metadata/index.If path arguments must remain for compatibility, resolve the path with
`Path(path).resolve()` and reject it unless it is under
`artifact_store.base_dir.resolve()`.Require a valid artifact metadata sidecar for read helpers. Files not
created by `FileSystemArtifactStore.store()` should not be readable through
artifact tools.Apply the same containment check to `load()`, `head()`, `tail()`, `grep()`,
`chunk()`, and `delete()`.Avoid returning absolute host paths in prompt-visible artifact references
when an opaque artifact ID would suffice.Minimal containment helper:This helper should be paired with metadata-sidecar validation so arbitrary
non-artifact files placed under the base directory are not automatically
treated as valid artifacts.
CVSS v3.1: 7.5