From bb1e97556dec20b37603219de8e72b1f4c485384 Mon Sep 17 00:00:00 2001 From: Lucas Berger Date: Sat, 13 Jun 2026 08:51:53 -0400 Subject: [PATCH] fix(16): fail closed on unparseable audit-waiver expiry date --- scripts/__tests__/check-audit.test.mjs | 17 +++++++++++++++++ scripts/check-audit.mjs | 9 +++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/scripts/__tests__/check-audit.test.mjs b/scripts/__tests__/check-audit.test.mjs index d6aaa3d..9ecddb4 100644 --- a/scripts/__tests__/check-audit.test.mjs +++ b/scripts/__tests__/check-audit.test.mjs @@ -76,6 +76,16 @@ const noExpiryAllowlist = { }, }; +// Fixture: allowlist whose expiry date is malformed (typo). Must fail CLOSED — +// a bad date can never grant an indefinite waiver. +const malformedExpiryAllowlist = { + 'GHSA-gv7w-rqvm-qjhr': { + reason: 'esbuild dev transitive — not in production runtime', + reviewer: 'luc', + expires: '2026-13-99', + }, +}; + test('unwaived High advisory is blocking', () => { const blocking = selectBlocking(highUnwaived, emptyAllowlist); assert.equal(blocking.length, 1); @@ -123,4 +133,11 @@ test('isWaived: future expiry waives, past expiry does not, missing entry does n assert.equal(isWaived(adv, expiredAllowlist), false); // past expiry assert.equal(isWaived(adv, noExpiryAllowlist), true); // no expiry → indefinite waive assert.equal(isWaived(adv, emptyAllowlist), false); // not listed + assert.equal(isWaived(adv, malformedExpiryAllowlist), false); // unparseable expiry → fail closed +}); + +test('malformed expiry fails closed — High advisory re-blocks', () => { + const blocking = selectBlocking(highWaived, malformedExpiryAllowlist); + assert.equal(blocking.length, 1); + assert.equal(blocking[0].github_advisory_id, 'GHSA-gv7w-rqvm-qjhr'); }); diff --git a/scripts/check-audit.mjs b/scripts/check-audit.mjs index 5b9719d..08c9e74 100644 --- a/scripts/check-audit.mjs +++ b/scripts/check-audit.mjs @@ -37,8 +37,13 @@ const BLOCKING_SEVERITIES = new Set(['high', 'critical']); export function isWaived(adv, allowlist) { const w = allowlist[adv.github_advisory_id]; if (!w) return false; - // No expiry or future expiry → waived; past (or equal) expiry → NOT waived (re-blocks). - if (w.expires && Date.parse(w.expires) <= Date.now()) return false; + // No expiry → waived; future expiry → waived; past/equal expiry → NOT waived. + // An unparseable `expires` (typo) fails CLOSED: treated as expired so a malformed + // date can never grant an indefinite waiver (same failure class as CR-01). + if (w.expires) { + const ts = Date.parse(w.expires); + if (Number.isNaN(ts) || ts <= Date.now()) return false; + } return true; }