mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-28 01:21:36 +00:00
refactor: unify boundary hardening for file reads
This commit is contained in:
@@ -231,6 +231,46 @@ describe("discoverOpenClawPlugins", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("rejects package extension entries that are hardlinked aliases", async () => {
|
||||
if (process.platform === "win32") {
|
||||
return;
|
||||
}
|
||||
const stateDir = makeTempDir();
|
||||
const globalExt = path.join(stateDir, "extensions", "pack");
|
||||
const outsideDir = path.join(stateDir, "outside");
|
||||
const outsideFile = path.join(outsideDir, "escape.ts");
|
||||
const linkedFile = path.join(globalExt, "escape.ts");
|
||||
fs.mkdirSync(globalExt, { recursive: true });
|
||||
fs.mkdirSync(outsideDir, { recursive: true });
|
||||
fs.writeFileSync(outsideFile, "export default {}", "utf-8");
|
||||
try {
|
||||
fs.linkSync(outsideFile, linkedFile);
|
||||
} catch (err) {
|
||||
if ((err as NodeJS.ErrnoException).code === "EXDEV") {
|
||||
return;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(globalExt, "package.json"),
|
||||
JSON.stringify({
|
||||
name: "@openclaw/pack",
|
||||
openclaw: { extensions: ["./escape.ts"] },
|
||||
}),
|
||||
"utf-8",
|
||||
);
|
||||
|
||||
const { candidates, diagnostics } = await withStateDir(stateDir, async () => {
|
||||
return discoverOpenClawPlugins({});
|
||||
});
|
||||
|
||||
expect(candidates.some((candidate) => candidate.idHint === "pack")).toBe(false);
|
||||
expect(diagnostics.some((entry) => entry.message.includes("escapes package directory"))).toBe(
|
||||
true,
|
||||
);
|
||||
});
|
||||
|
||||
it.runIf(process.platform !== "win32")("blocks world-writable plugin paths", async () => {
|
||||
const stateDir = makeTempDir();
|
||||
const globalExt = path.join(stateDir, "extensions");
|
||||
|
||||
Reference in New Issue
Block a user