test-suite/unit/upload-guard.test.mjs (view raw)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
import assert from "node:assert/strict";
import fs from "node:fs";
import os from "node:os";
import path from "node:path";
import { test } from "node:test";
import { assertUploadsStaged } from "../../broker/upload-guard.mjs";
const base = fs.realpathSync(fs.mkdtempSync(path.join(os.tmpdir(), "guard-")));
const stage = path.join(base, "stage");
fs.mkdirSync(stage);
fs.writeFileSync(path.join(stage, "ok.txt"), "x");
fs.writeFileSync(path.join(base, "secret.txt"), "s");
fs.symlinkSync(path.join(base, "secret.txt"), path.join(stage, "link.txt"));
const upload = (...paths) => () => assertUploadsStaged("page.upload", { paths }, stage);
test("a file in the staging directory is allowed", () => {
assert.doesNotThrow(upload(path.join(stage, "ok.txt")));
});
test("a file elsewhere, a ../ escape, a symlink out, a relative path and a missing file are refused", () => {
assert.throws(upload(path.join(base, "secret.txt")), /limited to files/);
assert.throws(upload(path.join(stage, "..", "secret.txt")), /limited to files/);
assert.throws(upload(path.join(stage, "link.txt")), /limited to files/);
assert.throws(upload("ok.txt"), /limited to files/);
assert.throws(upload(path.join(stage, "nope.txt")), /limited to files/);
});
test("one bad path among good ones refuses the lot", () => {
assert.throws(upload(path.join(stage, "ok.txt"), "/etc/hosts"), /limited to files/);
});
test("a missing staging directory refuses everything", () => {
assert.throws(() => assertUploadsStaged("page.upload", { paths: [path.join(stage, "ok.txt")] }, path.join(base, "none")), /limited to files/);
});
test("raw DOM.setFileInputFiles through cdp.call is held to the same rule", () => {
const call = (files) => () => assertUploadsStaged("cdp.call", { method: "DOM.setFileInputFiles", params: { files } }, stage);
assert.doesNotThrow(call([path.join(stage, "ok.txt")]));
assert.throws(call(["/etc/hosts"]), /limited to files/);
});
test("other commands are untouched", () => {
assert.doesNotThrow(() => assertUploadsStaged("page.click", { paths: ["/etc/hosts"] }, stage));
assert.doesNotThrow(() => assertUploadsStaged("cdp.call", { method: "Runtime.evaluate", params: {} }, stage));
});
|