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:
PraisonAIon PyPI - Affected surface: PraisonAI agents that register
write_fileor 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
workspaceis 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
Noneworkspace 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 usingopen,Path.write_text, orPath.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_filehelpers 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_APPROVEable 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.mdwhen 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.
Related recipes
- CVE-2026-47391 - PraisonAI A2A eval tool RCE
- a separate PraisonAI A2A boundary issue where unauthenticated prompt input can reach code-capable tools.
References
- GitHub Advisory: https://github.com/advisories/GHSA-hvhp-v2gc-268q
- Vendor advisory: https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-hvhp-v2gc-268q
- NVD CVE: https://nvd.nist.gov/vuln/detail/CVE-2026-47397
- GitLab Advisory Database: https://advisories.gitlab.com/pypi/praisonai/CVE-2026-47397/
- PraisonAI project: https://github.com/MervinPraison/PraisonAI