mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-07 23:21:23 +00:00
fix(security): enforce plugin and hook path containment
This commit is contained in:
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user