fix: remove vulnerable dependency chains

Replace build-time shell utilities with Node filesystem operations and retire the native sandbox example in favor of existing isolation options. Upgrade glob matching and worker-test dependencies and refresh the lockfiles.
This commit is contained in:
Armin Ronacher 2026-10-31 17:54:29 +01:00
parent 6de14ec098
commit b4c2e92acb
24 changed files with 260 additions and 857 deletions

View file

@ -10,15 +10,7 @@ const auditLevel = "moderate";
const severities = ["info", "low", "moderate", "high", "critical"];
/** @type {Record<string, { package: string; reason: string }>} */
const acceptedAdvisories = {
"GHSA-86w9-cpqp-85rv": {
package: "node-forge",
reason:
"No fixed node-forge release exists. It is only reachable through @earendil-works/gondolin in the private, " +
"unpublished gondolin example extension. Gondolin only verifies leaf certificates against its own locally " +
"generated CA (public exponent 65537), so the low-exponent signature forgery does not apply.",
},
};
const acceptedAdvisories = {};
const result = spawnSync("npm", ["audit", "--omit=dev", "--json"], { encoding: "utf8", maxBuffer: 64 * 1024 * 1024 });
if (result.error) {

30
scripts/package-files.mjs Normal file
View file

@ -0,0 +1,30 @@
// Cross-platform file operations for package build scripts, using only Node built-ins.
import { chmodSync, cpSync, globSync, mkdirSync, rmSync, statSync } from "node:fs";
import { basename, join } from "node:path";
const [command, ...paths] = process.argv.slice(2);
const usage = "Usage: package-files.mjs clean <paths...> | copy <sources...> <directory> | executable <files...>";
if (paths.length === 0) throw new Error(usage);
switch (command) {
case "clean":
for (const path of paths) rmSync(path, { recursive: true, force: true });
break;
case "copy": {
const destination = paths.pop();
if (!destination || paths.length === 0) throw new Error(usage);
mkdirSync(destination, { recursive: true });
for (const pattern of paths) {
const sources = globSync(pattern);
if (sources.length === 0) throw new Error(`No files match ${pattern}`);
for (const source of sources) cpSync(source, join(destination, basename(source)), { recursive: true });
}
break;
}
case "executable":
for (const path of paths) chmodSync(path, statSync(path).mode | 0o111);
break;
default:
throw new Error(usage);
}

View file

@ -0,0 +1,82 @@
// Exercises the file operations used by package build scripts without touching build output.
import assert from "node:assert/strict";
import { spawnSync } from "node:child_process";
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, statSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { test } from "node:test";
import { fileURLToPath } from "node:url";
const script = fileURLToPath(new URL("./package-files.mjs", import.meta.url));
function workspace(t) {
const directory = mkdtempSync(join(tmpdir(), "pi-package-files-"));
t.after(() => rmSync(directory, { recursive: true, force: true }));
return directory;
}
function run(directory, ...args) {
return spawnSync(process.execPath, [script, ...args], { cwd: directory, encoding: "utf8" });
}
test("clean removes directories and files and ignores missing paths", (t) => {
const directory = workspace(t);
mkdirSync(join(directory, "dist", "nested"), { recursive: true });
writeFileSync(join(directory, "dist", "nested", "file.js"), "output");
writeFileSync(join(directory, "output.txt"), "output");
assert.equal(run(directory, "clean", "dist", "output.txt", "missing").status, 0);
assert.equal(existsSync(join(directory, "dist")), false);
assert.equal(existsSync(join(directory, "output.txt")), false);
});
test("copy expands patterns, creates directories, and overwrites existing assets", (t) => {
const directory = workspace(t);
mkdirSync(join(directory, "source assets"));
writeFileSync(join(directory, "source assets", "dark.json"), "dark");
writeFileSync(join(directory, "source assets", "light.json"), "light");
writeFileSync(join(directory, "source assets", "ignored.txt"), "ignored");
const args = ["copy", "source assets/*.json", "output/assets"];
assert.equal(run(directory, ...args).status, 0);
assert.equal(readFileSync(join(directory, "output/assets/dark.json"), "utf8"), "dark");
assert.equal(readFileSync(join(directory, "output/assets/light.json"), "utf8"), "light");
assert.equal(existsSync(join(directory, "output/assets/ignored.txt")), false);
writeFileSync(join(directory, "source assets", "dark.json"), "updated");
assert.equal(run(directory, ...args).status, 0);
assert.equal(readFileSync(join(directory, "output/assets/dark.json"), "utf8"), "updated");
});
test("copy accepts multiple files and preserves directory names and nested contents", (t) => {
const directory = workspace(t);
mkdirSync(join(directory, "docs", "nested"), { recursive: true });
writeFileSync(join(directory, "docs", "nested", "guide.md"), "guide");
writeFileSync(join(directory, "README.md"), "readme");
assert.equal(run(directory, "copy", "docs", "README.md", "dist").status, 0);
assert.equal(readFileSync(join(directory, "dist", "docs", "nested", "guide.md"), "utf8"), "guide");
assert.equal(readFileSync(join(directory, "dist", "README.md"), "utf8"), "readme");
});
test("copy fails when an asset pattern matches nothing", (t) => {
const result = run(workspace(t), "copy", "missing/*.json", "dist");
assert.notEqual(result.status, 0);
assert.match(result.stderr, /No files match missing/);
});
test("executable adds executable bits without removing existing permissions", (t) => {
const directory = workspace(t);
for (const name of ["cli.js", "rpc.js"]) writeFileSync(join(directory, name), "entry", { mode: 0o640 });
const mode = statSync(join(directory, "cli.js")).mode;
assert.equal(run(directory, "executable", "cli.js", "rpc.js").status, 0);
if (process.platform !== "win32") {
assert.equal(statSync(join(directory, "cli.js")).mode & 0o777, (mode | 0o111) & 0o777);
assert.equal(statSync(join(directory, "rpc.js")).mode & 0o111, 0o111);
}
});
test("invalid commands and missing arguments fail", (t) => {
const directory = workspace(t);
for (const args of [[], ["unknown", "dist"], ["clean"], ["copy", "dist"], ["executable"]]) {
const result = run(directory, ...args);
assert.notEqual(result.status, 0);
assert.match(result.stderr, /Usage: package-files/);
}
});