mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-09 07:57:39 +00:00
fix(security): harden archive extraction (#16203)
* fix(browser): confine upload paths for file chooser * fix(browser): sanitize suggested download filenames * chore(lint): avoid control regex in download sanitizer * test(browser): cover absolute escape paths * docs(browser): update upload example path * refactor(browser): centralize upload path confinement * fix(infra): harden tmp dir selection * fix(security): harden archive extraction * fix(infra): harden tar extraction filter
This commit is contained in:
committed by
GitHub
parent
9a134c8a10
commit
3aa94afcfd
@@ -49,6 +49,21 @@ describe("archive utils", () => {
|
||||
expect(content).toBe("hi");
|
||||
});
|
||||
|
||||
it("rejects zip path traversal (zip slip)", async () => {
|
||||
const workDir = await makeTempDir();
|
||||
const archivePath = path.join(workDir, "bundle.zip");
|
||||
const extractDir = path.join(workDir, "a");
|
||||
|
||||
const zip = new JSZip();
|
||||
zip.file("../b/evil.txt", "pwnd");
|
||||
await fs.writeFile(archivePath, await zip.generateAsync({ type: "nodebuffer" }));
|
||||
|
||||
await fs.mkdir(extractDir, { recursive: true });
|
||||
await expect(
|
||||
extractArchive({ archivePath, destDir: extractDir, timeoutMs: 5_000 }),
|
||||
).rejects.toThrow(/(escapes destination|absolute)/i);
|
||||
});
|
||||
|
||||
it("extracts tar archives", async () => {
|
||||
const workDir = await makeTempDir();
|
||||
const archivePath = path.join(workDir, "bundle.tar");
|
||||
@@ -65,4 +80,20 @@ describe("archive utils", () => {
|
||||
const content = await fs.readFile(path.join(rootDir, "hello.txt"), "utf-8");
|
||||
expect(content).toBe("yo");
|
||||
});
|
||||
|
||||
it("rejects tar path traversal (zip slip)", async () => {
|
||||
const workDir = await makeTempDir();
|
||||
const archivePath = path.join(workDir, "bundle.tar");
|
||||
const extractDir = path.join(workDir, "extract");
|
||||
const insideDir = path.join(workDir, "inside");
|
||||
await fs.mkdir(insideDir, { recursive: true });
|
||||
await fs.writeFile(path.join(workDir, "outside.txt"), "pwnd");
|
||||
|
||||
await tar.c({ cwd: insideDir, file: archivePath }, ["../outside.txt"]);
|
||||
|
||||
await fs.mkdir(extractDir, { recursive: true });
|
||||
await expect(
|
||||
extractArchive({ archivePath, destDir: extractDir, timeoutMs: 5_000 }),
|
||||
).rejects.toThrow(/escapes destination/i);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user