Jul 15, 2026·5 min read·52 visits
Authenticated path traversal allows arbitrary host filesystem read, write, and deletion via URL-encoded characters due to improper path resolution logic.
The obsidian-local-rest-api plugin prior to version 4.1.3 is vulnerable to an authenticated path traversal flaw in its /vault/{path} endpoints. An authenticated attacker can bypass the vault root boundary using URL-encoded directory traversal sequences to perform unauthorized operations on the host filesystem.
The NPM package and Obsidian community plugin obsidian-local-rest-api provides a secure REST API and Model Context Protocol (MCP) server for local or remote interaction with an Obsidian vault.
Prior to version 4.1.3, the plugin exposes an authenticated path traversal vulnerability in its /vault/{path} endpoints. This vulnerability is classified under CWE-22, denoting improper limitation of a pathname to a restricted directory.
An authenticated attacker possessing a valid REST API bearer token can escape the restricted sandbox of the Obsidian vault root. This allows the attacker to interact with the underlying host filesystem using the privileges of the active user executing the Obsidian application.
The attack surface is exposed via several standard REST API endpoints. These endpoints handle resource retrieval, modification, deletion, and relocation.
The vulnerability stems from the processing pipeline applied to the request URL path in the Express web framework combined with custom path decoding.
When a client issues an HTTP request containing percent-encoded slashes, the routing layer in Express does not interpret those encoded characters as path delimiters. Consequently, a URI path such as /vault/..%2Fetc%2Fpasswd is successfully routed to the handler for /vault/:path as a single parameter.
The application subsequently executes a substring operation to strip the initial route segment. The remaining string segment is then processed using the standard decodeURIComponent utility.
Decoding translates the percent-encoded sequences into raw directory traversal sequences. The resulting unsanitized file path is passed directly to the filesystem adapter without further validation.
In vulnerable versions (4.1.2 and below), the route handlers inside src/requestHandler.ts extract user input paths directly from the request properties without validation.
async vaultGet(req: express.Request, res: express.Response): Promise<void> {
const path = decodeURIComponent(
req.path.slice(req.path.indexOf("/", 1) + 1),
);
return this._vaultGet(path, req, res);
}The implementation extracts the path string and decodes it immediately before invoking the private _vaultGet helper. The system lacks any logical checks to ensure that the resolved path does not traverse above the parent vault directory.
To resolve this flaw, the maintainer introduced the extractVaultPath sanitization helper in version 4.1.3.
private extractVaultPath(req: express.Request, res: express.Response): string | null {
let decoded: string;
try {
decoded = decodeURIComponent(req.path.slice(req.path.indexOf("/", 1) + 1));
} catch {
this.returnCannedResponse(res, { errorCode: ErrorCode.PathTraversalNotAllowed });
return null;
}
const syntheticRoot = "/vault";
const resolved = posix.resolve(syntheticRoot, decoded);
if (resolved !== syntheticRoot && !resolved.startsWith(syntheticRoot + "/")) {
this.returnCannedResponse(res, { errorCode: ErrorCode.PathTraversalNotAllowed });
return null;
}
return decoded;
}The updated implementation resolves the decoded path against a synthetic root (/vault) using the posix.resolve algorithm. It then explicitly checks whether the resolved path either matches the synthetic root or remains within its subdirectories. This design stops traversal strings from referencing files outside the vault.
Exploitation requires the attacker to possess a valid Bearer token, which must be supplied in the Authorization header of each HTTP request.
Once authenticated, an attacker can craft a target URI containing multiple percent-encoded traversal sequences (..%2F) to reach the root of the host operating system.
The following HTTP transaction demonstrates how an attacker can leverage a GET request to retrieve the host configuration file on a Unix-based system:
GET /vault/..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2F..%2Fetc%2Fpasswd HTTP/1.1
Host: 127.0.0.1:8000
Authorization: Bearer <VALID_BEARER_TOKEN>
Accept: */*If the application is vulnerable, the backend decodes the parameter to ../../../../../../../../../../../../../../../../../../../../etc/passwd and returns the file content with an HTTP 200 status code.
Write operations are similarly executed by leveraging PUT or POST methods against the directory traversal endpoints. An attacker can write script payloads directly to critical system shell configurations, such as .bashrc or .bash_profile, to achieve remote code execution when the local user opens a terminal session.
The impact of this vulnerability is critical due to the potential for arbitrary file write and subsequent execution on the host machine.
Because the REST API handles PUT, POST, DELETE, and MOVE requests, an attacker can modify files on the operating system with the permissions of the user running Obsidian.
When calculating CVSS severity, the vector depends on the network exposure of the API listener. If the listener is bound strictly to the local loopback interface, the CVSS 3.1 vector is CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H resulting in a High severity score of 8.2.
However, if the REST API port is exposed to a local area network or accessed via a cross-site scripting/DNS rebinding attack vector, the CVSS 3.1 vector evaluates to CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H, producing a Critical severity score of 9.1.
The primary remediation strategy is upgrading the obsidian-local-rest-api plugin to version 4.1.3 or higher. This update replaces the vulnerable path parsing logic with the sanitized extractVaultPath resolution checks.
System administrators and security teams can deploy Snort rules to detect traversal patterns in HTTP requests targeting ports commonly used by this plugin.
alert tcp any any -> any [8000,8443] (msg:"Obsidian Local REST API Path Traversal Attempt (GHSA-62gx-5q78-wrvx)"; flow:to_server,established; content:"/vault/"; http_uri; content:"..%2F"; nocase; http_uri; sid:1000001; rev:1;)Network detection should look for the literal string /vault/ followed by URL-encoded directory traversal signatures (..%2F or ..%2f). Additionally, logs containing HTTP requests can be monitored for the presence of these encoded characters in the requested path parameters.
CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:C/C:H/I:H/A:H| Product | Affected Versions | Fixed Version |
|---|---|---|
obsidian-local-rest-api coddingtonbear | < 4.1.3 | 4.1.3 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-22 |
| Attack Vector | Network / Local |
| CVSS Score | 9.1 (Critical) |
| Impact | Arbitrary File Read, Write, Append, Deletion, and Remote Code Execution |
| Exploit Status | PoC Documented |
| KEV Status | Not Listed |
The software uses external input to construct a pathname that should be within a restricted directory, but it does not properly neutralize elements within the pathname that can resolve to a location outside of the restricted directory.
A remote code execution vulnerability exists in Microsoft .NET due to untrusted data deserialization within the PresentationCore component. The flaw stems from implicit auto-conversion flags during clipboard data retrieval operations.
An out-of-bounds write vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio allows unauthenticated remote attackers to execute arbitrary code via crafted pixel-shader bytecode or auto-converted clipboard payloads.
ASP.NET Core contains a thread deadlock vulnerability (CWE-833) that allows an unauthenticated remote attacker to cause a denial of service over the network by exhausting server thread pool resources.
CVE-2026-70035 is a high-severity Remote Code Execution (RCE) vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio caused by improper handling during the deserialization of untrusted data (CWE-502). An unauthenticated attacker can execute arbitrary code within the context of the affected process by delivering a crafted serialized payload.
An elevation of privilege vulnerability exists in ASP.NET Core and Microsoft Visual Studio due to improper synchronization during concurrent thread execution. Authenticated remote attackers with low privileges can exploit a timing window to manipulate shared resources and assume higher-level execution contexts.
A path traversal vulnerability (CWE-22) in Contao CMS allows unauthenticated remote attackers to bypass directory boundary restrictions in ImagesController and access files within the project directory.