CVE-2026-39308: PraisonAI: recipe registry path traversal file write
GHSA-r9x3-wx45-2v7f HIGH CISA: TRACK*PraisonAI's recipe registry publish endpoint blindly writes uploaded bundle files to filesystem paths derived from attacker-controlled manifest fields before performing any validation, allowing any publisher — or any network client on an unauthenticated registry — to plant arbitrary files outside the configured registry root. Even though the final request returns HTTP 400, the file write is permanent, making this a silent, error-masked attack that typical success-based alerting will completely miss. With CVSS 7.1 (High), a network-accessible attack vector, and low privilege requirements, exploitation is straightforward for any deployment that exposes the recipe registry — and with 6 other CVEs already recorded in this package, the codebase has a pattern of systemic security debt that warrants broader scrutiny. Upgrade to PraisonAI >= 4.5.113 immediately; if patching is not possible, take the recipe registry publish endpoint offline or restrict it to trusted IP ranges, and audit the registry root's adjacent filesystem for unexpected .praison files.
What is the risk?
High risk for any deployment running the PraisonAI recipe registry service. CVSS 7.1 with a network-accessible vector and a low privilege bar means exploitation requires only publish access — or no access at all on open registries. The silent failure mode (HTTP 400 masks a successful write) drastically reduces detection probability and dwell time before discovery. The PoC is publicly documented in the GitHub advisory, eliminating research overhead for attackers. No KEV listing or active exploitation observed at time of analysis, but the recipe registry is by design a multi-tenant ingestion surface, making the exploitation path well-understood. Risk escalates sharply in environments where the registry process runs adjacent to web server roots, CI/CD artifact directories, or agent configuration stores.
What systems are affected?
| Package | Ecosystem | Vulnerable Range | Patched |
|---|---|---|---|
| PraisonAI | pip | <= 4.5.112 | 4.5.113 |
Do you use PraisonAI? You're affected.
Severity & Risk
Attack Surface
What should I do?
7 steps-
Patch: upgrade PraisonAI to >= 4.5.113 immediately — the fix validates manifest name and version fields before any path join or filesystem write.
-
If patching is not feasible, disable or firewall the recipe registry publish endpoint; it is not required for read-only or inference workloads.
-
If no authentication token is configured on the registry, enable one now and restrict publish permissions to trusted identities only.
-
Do not expose the registry service directly to the public internet without authentication.
-
Run an immediate audit of the registry root's parent directories and any adjacent writable paths for unexpected .praison files or recently modified config files.
-
Deploy file integrity monitoring (e.g., auditd on Linux, osquery) on the registry host, alerting on writes outside the configured registry root path.
-
For retrospective detection: search application logs for POST /v1/recipes/ requests returning HTTP 400 where the manifest name or version contains ../ or absolute path characters — these are indicators of exploitation attempts.
CISA SSVC Assessment
Source: CISA Vulnrichment (SSVC v2.0). Decision based on the CISA Coordinator decision tree.
Classification
Compliance Impact
This CVE is relevant to:
Frequently Asked Questions
What is CVE-2026-39308?
PraisonAI's recipe registry publish endpoint blindly writes uploaded bundle files to filesystem paths derived from attacker-controlled manifest fields before performing any validation, allowing any publisher — or any network client on an unauthenticated registry — to plant arbitrary files outside the configured registry root. Even though the final request returns HTTP 400, the file write is permanent, making this a silent, error-masked attack that typical success-based alerting will completely miss. With CVSS 7.1 (High), a network-accessible attack vector, and low privilege requirements, exploitation is straightforward for any deployment that exposes the recipe registry — and with 6 other CVEs already recorded in this package, the codebase has a pattern of systemic security debt that warrants broader scrutiny. Upgrade to PraisonAI >= 4.5.113 immediately; if patching is not possible, take the recipe registry publish endpoint offline or restrict it to trusted IP ranges, and audit the registry root's adjacent filesystem for unexpected .praison files.
Is CVE-2026-39308 actively exploited?
No confirmed active exploitation of CVE-2026-39308 has been reported, but organizations should still patch proactively.
How to fix CVE-2026-39308?
1. Patch: upgrade PraisonAI to >= 4.5.113 immediately — the fix validates manifest name and version fields before any path join or filesystem write. 2. If patching is not feasible, disable or firewall the recipe registry publish endpoint; it is not required for read-only or inference workloads. 3. If no authentication token is configured on the registry, enable one now and restrict publish permissions to trusted identities only. 4. Do not expose the registry service directly to the public internet without authentication. 5. Run an immediate audit of the registry root's parent directories and any adjacent writable paths for unexpected .praison files or recently modified config files. 6. Deploy file integrity monitoring (e.g., auditd on Linux, osquery) on the registry host, alerting on writes outside the configured registry root path. 7. For retrospective detection: search application logs for POST /v1/recipes/ requests returning HTTP 400 where the manifest name or version contains ../ or absolute path characters — these are indicators of exploitation attempts.
What systems are affected by CVE-2026-39308?
This vulnerability affects the following AI/ML architecture patterns: agent frameworks, AI development pipelines, model serving.
What is the CVSS score for CVE-2026-39308?
CVE-2026-39308 has a CVSS v3.1 base score of 7.1 (HIGH). The EPSS exploitation probability is 0.10%.
Technical Details
NVD Description
### Summary PraisonAI's recipe registry publish endpoint writes uploaded recipe bundles to a filesystem path derived from the bundle's internal `manifest.json` before it verifies that the manifest `name` and `version` match the HTTP route. A malicious publisher can place `../` traversal sequences in the bundle manifest and cause the registry server to create files outside the configured registry root even though the request is ultimately rejected with HTTP `400`. This is an arbitrary file write / path traversal issue on the registry host. It affects deployments that expose the recipe registry publish flow. If the registry is intentionally run without a token, any network client that can reach the service can trigger it. If a token is configured, any user with publish access can still exploit it. ### Details The bug is caused by the order of operations between the HTTP handler and the registry storage layer. 1. `RegistryServer._handle_publish()` in `src/praisonai/praisonai/recipe/server.py:370-426` parses `POST /v1/recipes/{name}/{version}`, writes the uploaded `.praison` file to a temporary path, and immediately calls: ```python result = self.registry.publish(tmp_path, force=force) ``` 2. `LocalRegistry.publish()` in `src/praisonai/praisonai/recipe/registry.py:214-287` opens the uploaded tarball, reads `manifest.json`, and trusts the attacker-controlled `name` and `version` fields: ```python name = manifest.get("name") version = manifest.get("version") recipe_dir = self.recipes_path / name / version recipe_dir.mkdir(parents=True, exist_ok=True) bundle_name = f"{name}-{version}.praison" dest_path = recipe_dir / bundle_name shutil.copy2(bundle_path, dest_path) ``` 3. Validation helpers already exist in the same file: ```python def _validate_name(name: str) -> bool: def _validate_version(version: str) -> bool: ``` but they are not called before the filesystem write. 4. Only after `publish()` returns does the route compare the manifest values with the URL values: ```python if result["name"] != name or result["version"] != version: self.registry.delete(result["name"], result["version"]) return self._error_response(...) ``` At that point the out-of-root artifact has already been created. The request returns an error, but the write outside the registry root remains on disk. Verified vulnerable behavior: - Request path: `/v1/recipes/safe/1.0.0` - Internal manifest name: `../../outside-dir` - Server response: HTTP `400` - Leftover artifact: `/tmp/praisonai-publish-traversal-poc/outside-dir-1.0.0.praison` This demonstrates that the write occurs before the consistency check and rollback. ### PoC Run the single verification script from the checked-out repository: ```bash cd "/Users/r1zzg0d/Documents/CVE hunting/targets/PraisonAI" python3 tmp/pocs/poc.py ``` Expected vulnerable output: ```text [+] Publish response status: 400 { "ok": false, "error": "Bundle name/version (../../outside-dir@1.0.0) doesn't match URL (safe@1.0.0)", "code": "error" } [+] Leftover artifact exists: True [+] Artifact under registry root: False [+] RESULT: VULNERABLE - upload was rejected, but an out-of-root artifact was still created. ``` Then verify the artifact manually: ```bash ls -l /tmp/praisonai-publish-traversal-poc/outside-dir-1.0.0.praison find /tmp/praisonai-publish-traversal-poc -maxdepth 2 | sort ``` What the script does internally: 1. Starts a local PraisonAI recipe registry server. 2. Builds a malicious `.praison` bundle whose internal `manifest.json` contains `name = ../../outside-dir`. 3. Uploads that bundle to the apparently safe route `/v1/recipes/safe/1.0.0`. 4. Receives the expected `400` mismatch error. 5. Confirms that `outside-dir-1.0.0.praison` was still written outside the configured registry directory. ### Impact This is a path traversal / arbitrary file write vulnerability in the recipe registry publish flow. Impacted parties: - Registry operators running the PraisonAI recipe registry service. - Any deployment that allows remote recipe publication. - Any environment where adjacent writable filesystem locations contain sensitive application data, service files, or staged content that could be overwritten or planted. Security impact: - Integrity impact is high because an attacker can create or overwrite files outside the registry root. - Availability impact is possible if the attacker targets adjacent runtime or application files. - The issue can be chained with other local loading or deployment behaviors if nearby files are later consumed by another component. ### Remediation 1. Validate `manifest.json` `name` and `version` before any path join or filesystem write. Reject path separators, `..`, absolute paths, and any value that fails the existing `_validate_name()` / `_validate_version()` checks. 2. Resolve the final destination path and enforce that it remains under the configured registry root before calling `mkdir()` or `copy2()`. For example, compare the resolved destination against `self.recipes_path.resolve()`. 3. Move the URL-to-manifest consistency check ahead of `self.registry.publish(...)`, or refactor `publish()` so it receives already-validated route parameters instead of trusting attacker-controlled manifest values for storage paths.
Exploitation Scenario
An attacker with publish access (or network access to an open, unauthenticated registry) crafts a malicious .praison tarball where manifest.json sets name to ../../webroot and version to shell.php. They POST the bundle to the benign-looking route /v1/recipes/legitimate-tool/1.0.0. The server extracts the manifest, constructs the path webroot/shell.php relative to the registry root, writes the file, then returns HTTP 400 — which appears in logs as a failed, rejected request. If the registry runs on the same host as a PHP-capable web server, the attacker immediately has remote code execution via the planted web shell. In a pure agent context, the attacker targets the directory containing agent tool definition files or cron scripts, planting a backdoored .praison bundle that is loaded on the next scheduled agent invocation — achieving persistence with no successful-looking request in any log.
Weaknesses (CWE)
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L References
Timeline
Related Vulnerabilities
GHSA-vc46-vw85-3wvm 9.8 PraisonAI: RCE via malicious workflow YAML execution
Same package: praisonai CVE-2026-39890 9.8 PraisonAI: YAML deserialization enables unauthenticated RCE
Same package: praisonai GHSA-9qhq-v63v-fv3j 9.8 PraisonAI: RCE via MCP command injection
Same package: praisonai GHSA-2763-cj5r-c79m 9.7 PraisonAI: RCE via shell injection in agent workflows
Same package: praisonai CVE-2026-44336 9.6 PraisonAI: MCP path traversal escalates to full RCE
Same package: praisonai