fix(security): block hook manifest path escapes

This commit is contained in:
Peter Steinberger
2026-02-14 14:00:17 +01:00
parent 3bbd29bef9
commit 18e8bd68c5
3 changed files with 88 additions and 2 deletions

View File

@@ -52,6 +52,16 @@ function resolvePackageHooks(manifest: HookPackageManifest): string[] {
return raw.map((entry) => (typeof entry === "string" ? entry.trim() : "")).filter(Boolean);
}
function resolveContainedDir(baseDir: string, targetDir: string): string | null {
const base = path.resolve(baseDir);
const resolved = path.resolve(baseDir, targetDir);
const relative = path.relative(base, resolved);
if (relative === ".." || relative.startsWith(`..${path.sep}`) || path.isAbsolute(relative)) {
return null;
}
return resolved;
}
function loadHookFromDir(params: {
hookDir: string;
source: HookSource;
@@ -129,7 +139,13 @@ function loadHooksFromDir(params: { dir: string; source: HookSource; pluginId?:
if (packageHooks.length > 0) {
for (const hookPath of packageHooks) {
const resolvedHookDir = path.resolve(hookDir, hookPath);
const resolvedHookDir = resolveContainedDir(hookDir, hookPath);
if (!resolvedHookDir) {
console.warn(
`[hooks] Ignoring out-of-package hook path "${hookPath}" in ${hookDir} (must be within package directory)`,
);
continue;
}
const hook = loadHookFromDir({
hookDir: resolvedHookDir,
source,