fix(exec): escape regex literals in allowlist path matching

This commit is contained in:
User
2026-03-03 04:47:08 +08:00
committed by Peter Steinberger
parent a4927ed8ee
commit 8da8756f76
2 changed files with 23 additions and 7 deletions

View File

@@ -82,13 +82,25 @@ describe("exec approvals allowlist matching", () => {
expect(match?.pattern).toBe("*");
});
it("requires a resolved path", () => {
const match = matchAllowlist([{ pattern: "bin/rg" }], {
rawExecutable: "bin/rg",
resolvedPath: undefined,
executableName: "rg",
it("matches absolute paths containing regex metacharacters", () => {
const plusPathCases = ["/usr/bin/g++", "/usr/bin/clang++"];
for (const candidatePath of plusPathCases) {
const match = matchAllowlist([{ pattern: candidatePath }], {
rawExecutable: candidatePath,
resolvedPath: candidatePath,
executableName: candidatePath.split("/").at(-1) ?? candidatePath,
});
expect(match?.pattern).toBe(candidatePath);
}
});
it("does not throw when wildcard globs are mixed with + in path", () => {
const match = matchAllowlist([{ pattern: "/usr/bin/*++" }], {
rawExecutable: "/usr/bin/g++",
resolvedPath: "/usr/bin/g++",
executableName: "g++",
});
expect(match).toBeNull();
expect(match?.pattern).toBe("/usr/bin/*++");
});
});

View File

@@ -111,6 +111,10 @@ function tryRealpath(value: string): string | null {
}
}
function escapeRegExpLiteral(input: string): string {
return input.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
function globToRegExp(pattern: string): RegExp {
let regex = "^";
let i = 0;
@@ -132,7 +136,7 @@ function globToRegExp(pattern: string): RegExp {
i += 1;
continue;
}
regex += ch.replace(/[.*+?^${}()|[\\]\\\\]/g, "\\$&");
regex += escapeRegExpLiteral(ch);
i += 1;
}
regex += "$";