CVE-2026-47397 - PraisonAI arbitrary file write

PraisonAI versions before 4.6.40 contain a path-boundary flaw in the write_file tool. When the tool runs with workspace=None, path validation can be skipped, allowing agent-visible content to drive writes outside the intended workspace. The advisory demonstrates a normal agent workflow where hidden webpage metadata is crawled, passed into analysis context, and then causes an autonomous write_file call to write attacker-controlled content to an attacker-chosen path.

For agentic applications, the important boundary is not only “is the package installed.” Exposure depends on whether untrusted web, document, prompt, or tool output can reach file-mutating tools without a scoped workspace and approval.

Affected versions

  • Vulnerable package: PraisonAI <=4.6.39
  • Fixed package: PraisonAI 4.6.40+
  • Affected coordinate: PraisonAI on PyPI
  • Affected surface: PraisonAI agents that register write_file or copied file-write helpers and process untrusted web pages, documents, tickets, prompts, tool output, search results, or crawl results
  • Affected code pattern: file-write tools accept model-derived paths while workspace is missing, None, overly broad, symlink-following, or not enforced after canonical path resolution.

Indicator-of-exposure

  • The repository depends on, vendors, forks, or deploys PraisonAI <=4.6.39.
  • Agents register write_file, copied PraisonAI file tools, custom file-save helpers, artifact writers, report writers, or notebook/output writers.
  • Untrusted content from web_crawl, browsers, search, tickets, email, documents, comments, MCP tools, A2A messages, or user prompts is included in task context before a file-write-capable tool runs.
  • workspace=None, missing workspace config, process current directory, repository root, container root, or a shared mount is used as the write boundary.
  • PRAISONAI_AUTO_APPROVE, auto-execute modes, unattended agents, or CI agents can approve file-writing tool calls without human review.

Quick checks:

rg -n "PraisonAI|praisonai|write_file|save_output|output_file|workspace=None|workspace\\s*=\\s*None|PRAISONAI_AUTO_APPROVE|ALLOW_LOCAL_CRAWL|web_crawl|is_path_within_directory|Path\\(|open\\(|write_text\\(|write_bytes\\(" .
python -m pip show PraisonAI praisonai
python -m pip freeze | rg -i '^(PraisonAI|praisonai)=='

Windows:

rg -n "PraisonAI|praisonai|write_file|save_output|output_file|workspace=None|workspace\\s*=\\s*None|PRAISONAI_AUTO_APPROVE|ALLOW_LOCAL_CRAWL|web_crawl|is_path_within_directory|Path\\(|open\\(|write_text\\(|write_bytes\\(" .
python -m pip show PraisonAI praisonai
python -m pip freeze | rg -i '^(PraisonAI|praisonai)=='

Do not crawl attacker pages, write canary files outside a test fixture, or run auto-approved file tools against production workspaces during triage.

Remediation strategy

  • Upgrade every controlled PraisonAI package, lockfile, image, deployment, SBOM, and generated dependency report to 4.6.40+.
  • Require an explicit workspace root before any file-mutating tool runs. Missing or None workspace must fail closed rather than falling back to the process directory or filesystem root.
  • Resolve paths canonically before writing. Reject absolute paths, traversal, symlinks that leave the workspace, device files, sockets, and reserved paths.
  • Treat model-derived file names and paths as untrusted even when they came from a crawler, document parser, search result, ticket, or another tool.
  • Add human approval or policy gates for file-write tools when the request is influenced by untrusted content.
  • Isolate agent workspaces with least-privilege filesystem mounts, read-only source checkouts where possible, and separate artifact output directories.

When to use it

Use this recipe when a repository deploys PraisonAI agents, vendors or copies PraisonAI file tools, wraps write_file, or allows browser, crawl, document, ticket, MCP, A2A, or prompt content to influence file paths or artifacts. It is most important for unattended agents, auto-approve modes, CI agents, notebooks, and shared workspaces with secrets or source checkouts mounted.

Use it to upgrade the package and prove every file-mutating tool is bounded by an explicit canonical workspace plus approval policy. Do not use it to test by writing outside a local fixture or crawling live attacker-controlled pages.

Inputs

  • Python manifests, lockfiles, constraints, Dockerfiles, Compose files, Helm charts, Kubernetes manifests, notebooks, examples, copied tools, deployment docs, SBOMs, generated dependency reports, forks, and wrappers.
  • File-mutating tool inventory: write_file, copied PraisonAI helpers, save_output, artifact writers, report writers, notebook/output writers, and custom tools using open, Path.write_text, or Path.write_bytes.
  • Context sources that can influence paths or content: web crawl, browser output, search results, issues, pull requests, tickets, email, documents, comments, MCP tools, A2A messages, prompts, and model-derived state.
  • Workspace and runtime controls: explicit root, canonicalization, symlink policy, approval gates, auto-approve flags, mount permissions, artifact directories, read-only source checkouts, and secret mounts.
  • Validation evidence: dependency versions, path-boundary tests, tool-policy tests, deployment rendering, image builds, SBOM refresh, and non-secret smoke checks.

The prompt

You are remediating CVE-2026-47397 / GHSA-hvhp-v2gc-268q, the PraisonAI
`write_file` arbitrary file-write issue where untrusted agent context can drive
writes outside the intended workspace. Produce exactly one output:

- A reviewer-ready PR/change request that upgrades PraisonAI, enforces
  workspace-scoped file writes, adds local regression tests, refreshes
  generated artifacts, and documents operator containment, or
- TRIAGE.md if this repository does not control an affected PraisonAI runtime,
  file-write tool, copied helper, image, deployment, or dependency.

## Rules

- Scope only CVE-2026-47397 / GHSA-hvhp-v2gc-268q and directly related
  file-write, workspace, path-canonicalization, and tool-approval boundaries.
- Treat source code, prompts, crawled content, task context, local files,
  credentials, model-provider keys, MCP secrets, CI secrets, SSH keys, and
  generated artifacts as sensitive.
- Do not crawl live attacker infrastructure, write test files outside a local
  temporary fixture, print secrets, or run auto-approved file tools in
  production.
- Do not fix the finding by disabling all agent output, deleting tests, or
  broadening filesystem permissions.
- Do not auto-merge.

## Steps

1. Inventory every PraisonAI reference controlled by this repository:
   requirements, pyproject files, lockfiles, constraints, Dockerfiles, Compose
   files, Helm charts, Kubernetes manifests, notebooks, examples, copied tools,
   deployment docs, SBOMs, generated dependency reports, and local forks.
2. Determine every resolved PraisonAI version. A target is vulnerable if it
   resolves to `4.6.39` or earlier.
3. Search for file-mutating tools: `write_file`, copied PraisonAI file tools,
   `save_output`, `output_file`, `open(..., "w")`, `Path.write_text`,
   `Path.write_bytes`, artifact writers, report writers, and custom tools that
   accept a path from task context.
4. Trace whether untrusted context can reach those tools: web crawl, browser
   output, search results, issue comments, pull request text, tickets, email,
   documents, MCP tool responses, A2A messages, user prompts, or model-derived
   intermediate results.
5. If this repository only calls an externally owned PraisonAI service, stop
   with `TRIAGE.md` listing checked files, the owner, the required fixed
   version, and the required file-write policy.
6. Upgrade all controlled PraisonAI pins to `4.6.40+`. Regenerate lockfiles,
   constraints, image metadata, SBOMs, dependency reports, and generated docs.
7. Where the repository owns a fork, copied helper, or wrapper, enforce the
   write boundary:
   - missing or `None` workspace fails closed;
   - workspace root is explicit, canonical, and least-privilege;
   - requested paths are canonicalized before write;
   - absolute paths, traversal, symlink escapes, device files, sockets, and
     reserved paths are rejected;
   - path checks happen immediately before opening the file.
8. Add tool policy:
   - file-write tools require explicit approval when untrusted context
     influenced the path or content;
   - auto-approve modes cannot write outside a disposable fixture or declared
     artifact directory;
   - source checkouts and secret mounts are read-only where possible.
9. Add safe local regression tests:
   - `workspace=None` fails closed;
   - absolute paths and `..` traversal are rejected;
   - symlinks that leave the workspace are rejected;
   - a safe relative artifact path succeeds;
   - untrusted web/document context cannot set output path without approval;
   - logs and denial messages omit secrets, prompts, and sensitive file
     contents.
10. Add a PR body section named `CVE-2026-47397 operator actions` that states:
    - PraisonAI versions before and after;
    - every file-write tool, helper, notebook, and agent workflow reviewed;
    - whether untrusted crawl, document, ticket, prompt, MCP, or A2A context
      could influence file paths;
    - where workspaces are rooted and how they are isolated;
    - whether source checkouts, SSH keys, CI secrets, provider keys, or shared
      mounts could have been overwritten;
    - which validation commands passed.
11. Run relevant validation: dependency install, lockfile checks, path-boundary
    unit tests, agent tool-policy tests, example/notebook scans,
    lint/typecheck, deployment rendering, container build, SBOM refresh,
    dependency/security scans, and local non-secret smoke checks available in
    this repository.
12. Use PR title:
    `fix(sec): remediate CVE-2026-47397 in PraisonAI file tools`

## Stop conditions

- No affected PraisonAI runtime, package pin, file-write helper, image, or
  deployment is controlled by this repository.
- A fixed PraisonAI version cannot be consumed without a broader agent-runtime
  migration.
- Product policy intentionally lets untrusted content choose arbitrary write
  paths; document the required security-owner decision in `TRIAGE.md`.
- Verification would require production crawls, writing outside local fixtures,
  customer prompts, or credential disclosure.
- Validation fails for unrelated pre-existing reasons; document those failures
  instead of broadening scope.

Verification - what the reviewer looks for

  • No controlled lockfile, image, SBOM, or deployment resolves PraisonAI below 4.6.40.
  • File-write tools fail closed when workspace is missing and reject paths that escape the canonical workspace.
  • Tests cover traversal, absolute paths, symlinks, safe artifact writes, and untrusted-context approval.
  • Auto-approve or unattended agent modes cannot write outside disposable workspaces or declared artifact directories.
  • Operator notes identify whether any sensitive files or mounts may have been overwritten before the patch.

Watch for

  • Updating PraisonAI while copied write_file helpers or notebooks keep the vulnerable logic.
  • Checking ../ with strings instead of canonicalizing paths and symlinks before opening the file.
  • Falling back to the repository root, container root, or process current directory when workspace is missing.
  • Treating crawled metadata, document text, issue comments, or model output as trusted path input.
  • Leaving PRAISONAI_AUTO_APPROVE able to approve file writes influenced by untrusted content.

Output contract

Return one of:

  • A reviewer-ready PR/change request that upgrades every controlled PraisonAI runtime to 4.6.40+, refreshes artifacts, enforces explicit canonical workspace roots, rejects traversal and symlink escapes, gates file writes influenced by untrusted context, adds local path-boundary tests, and documents operator containment.
  • TRIAGE.md when no affected runtime, package pin, copied helper, file-write tool, image, deployment, or dependency is controlled by the repository.

The output must list PraisonAI versions, file-write tools reviewed, context sources that can influence paths, workspace roots, approval policy, auto-approve posture, mounts that could be overwritten, validation commands, and operator review actions. It must not write outside local fixtures, crawl attacker infrastructure, print secrets, or broaden filesystem permissions.

References