CVE-2026-39308
Python vulnerability analysis and mitigation

Overview

CVE-2026-39308 is a path traversal / arbitrary file write vulnerability in PraisonAI's recipe registry publish endpoint, classified as CWE-22. The flaw allows a malicious publisher to embed ../ sequences in a recipe bundle's manifest.json, causing the registry server to write files outside the configured registry root — even though the HTTP request is ultimately rejected with a 400 error. It affects all PraisonAI versions up to and including 4.5.112 (pip package). The vulnerability was published by the researcher R1ZZG0D on April 5, 2026, with the GitHub Advisory Database entry updated April 7, 2026. It carries a CVSS v3.1 base score of 7.1 (High) (GitHub Advisory, PraisonAI Advisory).

Technical details

The root cause is an incorrect order of operations in RegistryServer._handle_publish() (server.py:370-426) and LocalRegistry.publish() (registry.py:214-287). When a POST request arrives at /v1/recipes/{name}/{version}, the handler writes the uploaded .praison tarball to a temporary path and immediately calls self.registry.publish(tmp_path, force=force). Inside publish(), the code reads name and version directly from the attacker-controlled manifest.json and uses them unsanitized to construct the destination path via self.recipes_path / name / version, calling recipe_dir.mkdir(parents=True, exist_ok=True) and shutil.copy2(bundle_path, dest_path) before any validation. Although _validate_name() and _validate_version() helpers exist in the same file, they are never invoked prior to the filesystem write; the URL-to-manifest consistency check only occurs after publish() returns, at which point the out-of-root file already exists on disk (GitHub Advisory, PraisonAI Advisory).

Impact

An attacker can create or overwrite arbitrary files anywhere on the registry host filesystem that the server process has write access to, resulting in a high integrity impact. If the attacker targets adjacent runtime files, configuration files, or application code consumed by other components, this can be chained into remote code execution. Availability is also at risk if critical service files are overwritten or corrupted. Confidentiality is not directly impacted by this vulnerability. The attack surface includes any deployment exposing the recipe registry publish flow — unauthenticated if no token is configured, or exploitable by any user with publish access when a token is in use (GitHub Advisory, PraisonAI Advisory).

Exploitability

A proof-of-concept Python script is publicly available in the GitHub security advisory, demonstrating reliable exploitation against a local PraisonAI registry instance. The PoC starts a local registry, uploads a malicious bundle with name = ../../outside-dir in manifest.json, receives an HTTP 400 response, and confirms the out-of-root artifact was written to disk. There is no current evidence of in-the-wild exploitation. The EPSS score is approximately 0.057% (0.095% per the advisory), placing it in the 26th percentile for exploitation likelihood. The vulnerability is not listed in the CISA KEV catalog (GitHub Advisory, PraisonAI Advisory).

Exploitation steps

  1. Reconnaissance: Identify internet-facing or network-accessible PraisonAI recipe registry instances running version ≤ 4.5.112. Determine whether the registry requires a publish token or is open to unauthenticated requests.
  2. Craft malicious bundle: Create a .praison tarball containing a manifest.json where the name field includes path traversal sequences, e.g., "name": "../../outside-dir" and "version": "1.0.0".
  3. Upload to a benign-looking route: Send an HTTP POST request to /v1/recipes/safe/1.0.0 with the malicious .praison bundle as the body. If a token is required, use a valid publish token.
  4. Trigger the write: The server's LocalRegistry.publish() reads the attacker-controlled manifest.json, constructs the path self.recipes_path / ../../outside-dir / 1.0.0, creates the directory, and copies the bundle to outside-dir-1.0.0.praison outside the registry root — before any validation occurs.
  5. Observe the response: The server returns HTTP 400 (Bundle name/version doesn't match URL), but the file has already been written to the traversed path.
  6. Verify and chain: Confirm the artifact exists at the traversed location (e.g., /tmp/praisonai-publish-traversal-poc/outside-dir-1.0.0.praison). Chain with other attack primitives if the written file is later consumed by another application component to achieve code execution (GitHub Advisory, PraisonAI Advisory).

Indicators of compromise

  • Network: Unexpected HTTP POST requests to /v1/recipes/{name}/{version} where the response is HTTP 400 but the request body contains a .praison bundle; repeated publish attempts with varying name values from the same source IP.
  • File System: Presence of .praison files outside the configured registry root directory (e.g., in parent directories or unrelated application paths); newly created directories with names matching path traversal patterns (e.g., outside-dir) in unexpected filesystem locations.
  • Logs: Registry server access logs showing POST requests to /v1/recipes/ endpoints returning HTTP 400 with error messages referencing Bundle name/version ... doesn't match URL; log entries indicating mkdir or file copy operations to paths outside the registry root.
  • Process: Unexpected file creation events by the PraisonAI registry server process in directories outside its configured recipes_path (GitHub Advisory).

Mitigation and workarounds

Upgrade PraisonAI to version 4.5.113 or later, which is the patched release addressing this vulnerability. As a configuration-based workaround, restrict network access to the recipe registry publish endpoint using firewall rules or reverse proxy ACLs to limit who can reach the service. If the registry is currently running without authentication, implement token-based authentication to reduce the attack surface. Operators should also audit the filesystem for unexpected .praison files outside the registry root as a post-incident check (GitHub Advisory, PraisonAI Advisory).

Community reactions

The vulnerability was reported by researcher R1ZZG0D and published by the maintainer MervinPraison on April 5, 2026, with a patch released the same day in version 4.5.113. A Bluesky post from cyberhub.blog referenced the advisory in June 2026. No significant broader media coverage or notable community debate has been identified beyond standard vulnerability database aggregation (GitHub Advisory).

Additional resources


SourceThis report was generated using AI

Related Python vulnerabilities:

CVE ID

Severity

Score

Technologies

Component name

CISA KEV exploit

Has fix

Published date

CVE-2026-59971CRITICAL10
  • Python logoPython
  • mysql-mcp-server
NoYesSep 11, 2026
CVE-2026-59177HIGH8.8
  • Python logoPython
  • esphome-device-builder
NoYesSep 09, 2026
CVE-2026-88006MEDIUM6.5
  • Python logoPython
  • open-webui
NoYesSep 10, 2026
CVE-2026-88005MEDIUM6.5
  • Python logoPython
  • open-webui
NoYesSep 10, 2026
CVE-2026-49836MEDIUM4.6
  • Python logoPython
  • psd-tools
NoYesSep 10, 2026

Free Vulnerability Assessment

Benchmark your Cloud Security Posture

Evaluate your cloud security practices across 9 security domains to benchmark your risk level and identify gaps in your defenses.

Request assessment

Get a personalized demo

Ready to see Wiz in action?

"Best User Experience I have ever seen, provides full visibility to cloud workloads."
David EstlickCISO
"Wiz provides a single pane of glass to see what is going on in our cloud environments."
Adam FletcherChief Security Officer
"We know that if Wiz identifies something as critical, it actually is."
Greg PoniatowskiHead of Threat and Vulnerability Management