Files
Public Source Publisher 72c93e51fb
Public source validation / verify (push) Successful in 1m20s
CertScope: update dependencies and deployment and CI (+2 areas)
Public changes compared with the previous published export:
4 files changed.

Affected areas:
- dependencies: 1 file
- deployment and CI: 1 file
- documentation: 1 file
- scripts: 1 file

Changed files:
- Added: ".gitea/workflows/ci.yml"
- Updated: "SECURITY.md"
- Updated: "package-lock.json"
- Added: "scripts/audit-dependencies.mjs"

Export provenance/manifests refreshed; excluded from the change summary.

Publish curated CertScope source from 9cd536d4e2dd485794e5f5accd70220de4a081de
2026-10-09 01:10:53 +00:00

155 lines
4.4 KiB
JavaScript

import fs from "node:fs";
import { spawnSync } from "node:child_process";
const ADVISORY_URL = "https://github.com/advisories/GHSA-vfj7-8cjw-p6xm";
const EXPECTED_VULNERABILITIES = [
"@next/eslint-plugin-next",
"braces",
"eslint-config-next",
"fast-glob",
"micromatch",
].sort();
const EXPECTED_VERSIONS = new Map([
["next", "16.3.8"],
["eslint-config-next", "16.3.8"],
["@next/eslint-plugin-next", "16.3.8"],
["fast-glob", "3.3.1"],
["micromatch", "4.0.8"],
["braces", "3.0.3"],
]);
function fail(message) {
console.error(`Dependency audit exception rejected: ${message}`);
process.exit(1);
}
function packageVersion(lock, name) {
const entry = lock.packages?.[`node_modules/${name}`];
return typeof entry?.version === "string" ? entry.version : null;
}
const npmCommand = process.platform === "win32" ? "npm.cmd" : "npm";
const audit = spawnSync(
npmCommand,
["audit", "--audit-level=moderate", "--json"],
{
encoding: "utf8",
maxBuffer: 8 * 1024 * 1024,
shell: process.platform === "win32",
windowsHide: true,
},
);
if (audit.error) {
fail(`npm audit could not start: ${audit.error.name}`);
}
if (audit.status !== 0 && audit.status !== 1) {
fail(`npm audit returned unexpected exit code ${audit.status}`);
}
let report;
try {
report = JSON.parse(audit.stdout);
} catch {
fail("npm audit returned invalid JSON");
}
if (report.auditReportVersion !== 2 || typeof report.vulnerabilities !== "object") {
fail("npm audit report schema changed");
}
const names = Object.keys(report.vulnerabilities).sort();
if (audit.status === 0) {
if (names.length !== 0) {
fail("npm audit exited cleanly but still reported vulnerabilities");
}
console.log("Full dependency audit is clean.");
process.exit(0);
}
if (JSON.stringify(names) !== JSON.stringify(EXPECTED_VULNERABILITIES)) {
fail(`unexpected vulnerability set: ${names.join(", ")}`);
}
const counts = report.metadata?.vulnerabilities;
if (
!counts ||
counts.info !== 0 ||
counts.low !== 0 ||
counts.moderate !== 0 ||
counts.high !== 5 ||
counts.critical !== 0 ||
counts.total !== 5
) {
fail("vulnerability counts differ from the reviewed exception");
}
const lock = JSON.parse(fs.readFileSync(new URL("../package-lock.json", import.meta.url), "utf8"));
for (const [name, expected] of EXPECTED_VERSIONS) {
const actual = packageVersion(lock, name);
if (actual !== expected) {
fail(`${name} changed from reviewed version ${expected} to ${actual ?? "missing"}`);
}
}
const vulnerabilities = report.vulnerabilities;
for (const name of EXPECTED_VULNERABILITIES) {
const item = vulnerabilities[name];
if (!item || item.severity !== "high" || !Array.isArray(item.via)) {
fail(`${name} no longer matches the reviewed high-severity audit shape`);
}
}
const directNames = EXPECTED_VULNERABILITIES.filter(
(name) => vulnerabilities[name].isDirect === true,
);
if (JSON.stringify(directNames) !== JSON.stringify(["eslint-config-next"])) {
fail(`unexpected direct dependency findings: ${directNames.join(", ") || "none"}`);
}
const expectedChain = new Map([
["eslint-config-next", "@next/eslint-plugin-next"],
["@next/eslint-plugin-next", "fast-glob"],
["fast-glob", "micromatch"],
["micromatch", "braces"],
]);
for (const [name, expectedVia] of expectedChain) {
if (!vulnerabilities[name].via.includes(expectedVia)) {
fail(`${name} no longer resolves through ${expectedVia}`);
}
}
const bracesAdvisories = vulnerabilities.braces.via.filter(
(entry) => entry && typeof entry === "object",
);
if (bracesAdvisories.length !== 1) {
fail("braces advisory count changed");
}
const advisory = bracesAdvisories[0];
if (
String(advisory.source) !== "1240992" ||
advisory.name !== "braces" ||
advisory.severity !== "high" ||
advisory.range !== "<=3.0.3" ||
advisory.url !== ADVISORY_URL
) {
fail("braces advisory identity or affected range changed");
}
const fix = vulnerabilities["eslint-config-next"].fixAvailable;
if (
!fix ||
typeof fix !== "object" ||
fix.name !== "eslint-config-next" ||
fix.version !== "14.2.35" ||
fix.isSemVerMajor !== true
) {
fail("npm now reports a different remediation; review and remove/update this exception");
}
console.log(
"Accepted reviewed dev-tooling exception only: GHSA-vfj7-8cjw-p6xm via eslint-config-next -> @next/eslint-plugin-next -> fast-glob -> micromatch -> braces@3.0.3.",
);
console.log("Production dependencies remain covered by the separate strict production audit.");