fix(security): enforce plugin and hook path containment

This commit is contained in:
Peter Steinberger
2026-02-19 15:34:58 +01:00
parent 10379e7dcd
commit 81b19aaa1a
14 changed files with 387 additions and 8 deletions

View File

@@ -1,3 +1,4 @@
import fs from "node:fs";
import path from "node:path";
export function isPathInside(basePath: string, candidatePath: string): boolean {
@@ -7,6 +8,30 @@ export function isPathInside(basePath: string, candidatePath: string): boolean {
return rel === "" || (!rel.startsWith(`..${path.sep}`) && rel !== ".." && !path.isAbsolute(rel));
}
function safeRealpathSync(filePath: string): string | null {
try {
return fs.realpathSync(filePath);
} catch {
return null;
}
}
export function isPathInsideWithRealpath(
basePath: string,
candidatePath: string,
opts?: { requireRealpath?: boolean },
): boolean {
if (!isPathInside(basePath, candidatePath)) {
return false;
}
const baseReal = safeRealpathSync(basePath);
const candidateReal = safeRealpathSync(candidatePath);
if (!baseReal || !candidateReal) {
return opts?.requireRealpath !== true;
}
return isPathInside(baseReal, candidateReal);
}
export function extensionUsesSkippedScannerPath(entry: string): boolean {
const segments = entry.split(/[\\/]+/).filter(Boolean);
return segments.some(