Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/permission/path-restriction.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,22 @@ test("workspace-relative paths are unrestricted", () => {
expect(r.isRestricted("src/index.ts", true)).toBe(false);
});

test("an empty-string root does not turn containment into allow-all", () => {
// Regression for CL-6700: root + sep === sep when root is "", which every
// absolute path starts with. A sensitive absolute path resolved against
// a provider that yields "" roots must still be denied.
const r = createPathRestriction(cwd, () => [""], home);
expect(r.isRestricted("/etc/passwd", false)).toBe(true);
expect(r.isRestricted("/etc/passwd", true)).toBe(true);
});

test("a root of exactly \"/\" is not the same bug: it is not an allow-all prefix", () => {
// Documents the non-bug: "/" + sep is "//", which "/etc/passwd" does not
// start with, so an unrelated absolute path stays outside the workspace.
const r = createPathRestriction(cwd, () => ["/"], home);
expect(r.isRestricted("/etc/passwd", false)).toBe(true);
});

test("a directory sharing a string prefix with the workspace root is still restricted", async () => {
// "<cwd>baz" shares a string prefix with cwd but is a distinct sibling
// directory outside the workspace — the boundary check must not leak into
Expand Down
6 changes: 5 additions & 1 deletion src/permission/path-restriction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,12 @@ function realpathNearestOr(path: string): string {
}
}

// An empty root must never reach the prefix compare: `"" + sep` is just
// `sep` (e.g. "/" on Unix), which every absolute path starts with, turning
// containment into allow-all. A root of exactly `sep` itself is not this bug
// — `startsWith(sep + sep)` correctly rejects unrelated absolute paths.
const inKnownRoots = (real: string, roots: readonly string[]): boolean =>
roots.some((root) => real === root || real.startsWith(root + sep));
roots.some((root) => root.length > 0 && (real === root || real.startsWith(root + sep)));

// Resolves `path` (relative or absolute, possibly traversing `..`) against
// `cwd` and checks it against the workspace boundary: `cwd` itself plus every
Expand Down
Loading