moritzmyrz/coursevault-preview · Security

coursevault-preview has a path traversal due to improper base-directory boundary validation

GHSA ID
GHSA-9h9m-rr67-9jpg
CVE ID
CVE-2026-35613
Severity
medium
Published
Updated
CVSS
5.1 · CVSS:3.1/AV:L/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N
CVSS v3
5.1 · CVSS:3.1/AV:L/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N

Description

Summary

coursevault-preview versions prior to 0.1.1 contain a path traversal vulnerability in the resolveSafe utility. The boundary check used String.prototype.startsWith(baseDir) on a normalized path, which does not enforce a directory boundary. An attacker who controls the relativePath argument to affected CoursevaultPreview methods may be able to read files outside the configured baseDir when a sibling directory exists whose name shares the same string prefix.

Details

The vulnerable code in src/utils/errors.ts:

if (!full.startsWith(base)) {   // ← insufficient
  throw new Error("Path escapes the base directory");
}

Because the check is a raw string prefix test rather than a path-boundary test, the following bypass is possible:

baseDir  = "/srv/courses"
payload  = "../courses-admin/config.json"
resolved = "/srv/courses-admin/config.json"

"/srv/courses-admin/config.json".startsWith("/srv/courses") // → true ✗

Any file whose absolute path begins with the baseDir string — including files in sibling directories that share a name prefix — passes the guard and can be accessed by the caller through affected file-access methods.

The fix replaces the check with a separator-aware comparison:

if (full !== base && !full.startsWith(base + sep)) {
  throw new Error("Path escapes the base directory");
}

Impact

An application that passes untrusted input as the relativePath argument to affected file-access methods may expose file contents outside the intended directory.

  1. Attacker control over the relativePath parameter.
  2. A sibling directory on the filesystem whose name shares a string prefix with baseDir.

There is no network exposure in the package itself; impact is limited to local file disclosure within the host process's file system permissions.

CWEs

References