fix(security): fix all four web-ui advisories and raise the deploy audit gate to high (#1131) - #1149
Conversation
…dit gate to high (#1131) Two coupled loose ends from #1124: four open advisories, and a deploy gate at `--audit-level=critical` that could not see any of them. Raising the gate first would have blocked every deploy; fixing only the advisories would leave the gate blind again next time. All four were **fixed, not accepted**. Each had `fixAvailable: true` with no `effects`, so `npm audit fix` resolved them inside the existing major versions — no allowlist, no review date, because there is no residual risk to record. brace-expansion high 1.1.13 → 1.1.18, 2.1.1 → 2.1.4, 5.0.6 → 5.0.9 js-yaml high 3.14.2 → 3.15.1, 4.3.0 → 4.3.1 nanoid high 3.3.16 → 3.3.18 @babel/core low → 7.29.7 `npm audit` now reports 0 vulnerabilities; `npm test` (1280) and `npm run build` both pass. Only package-lock.json changed. Both deploy jobs move to `--audit-level=high`, with the reason inline. The tradeoff is explicit: audit results change without a code change, so a newly published high can block a deploy. That is the gate working — six highs accumulated unnoticed under `critical`. The decision itself lives in `tests/test_deploy_audit_gate_1131.py` rather than in a PR comment, alongside assertions that both jobs audit, that the level never weakens below high, and that no lockfile copy drops below what shipped here. That last table was green theatre on the first pass: I set the floors from the advisories' "patched in" versions, which the PRE-fix lockfile already satisfied, so all of it passed against the broken state. The floors now come from the shipped lockfile, and I verified the other way round — against main's lockfile the class fails 4/4.
|
Claude finished @frankbria's task in 7m 48s —— View job GLM precision bug-review — PR #1149✅ GLM review: no defects found. Scoped to concrete defects only (logic errors, null/error paths, security, data loss, races, breaking changes, resource leaks). Style, naming, architecture, and test-coverage are covered by the separate general review.
No inline findings to post. |
ReviewSolid, well-scoped fix — does exactly what #1131 asked (fix the advisories and raise the gate together, in that order) and backs the decision with a durable regression test rather than just a PR description. What's good:
Minor, non-blocking:
No security, performance, or test-coverage concerns beyond the above — this is exactly the kind of gate-plus-fix pairing the linked issue asked for. |
… stays valid
CI caught what local verification could not: `npm ci` refused the lockfile
`npm audit fix` produced —
npm error Missing: @emnapi/runtime@1.11.3 from lock file
npm error Missing: @emnapi/core@1.11.3 from lock file
npm error Invalid: lock file's @emnapi/wasi-threads@1.1.0 does not satisfy 1.2.3
Plain `npm audit fix` reconciles the lockfile against the *installed* tree, so
my npm 11.6.2 on this machine pruned two optional platform entries that CI's
npm (Node 20.19) expects. `--package-lock-only` edits the lockfile without
consulting node_modules and leaves all three @emnapi entries intact.
Same outcome for the four advisories (0 vulnerabilities, identical versions),
now starting from main's lockfile so the diff is only what the fix required.
Verified with a real `npm ci` before pushing this time, then `npm test` (1280)
and `npm run build`.
|
Claude finished @frankbria's task in 4m 18s —— View job Precision bug review — PR #1149 (synchronize)Scoped to concrete defects only (logic errors, null/error paths, security, data loss, races, breaking changes, resource leaks). Style/naming/architecture/test-coverage are covered by the separate general review.
✅ GLM review: no defects found. This run was triggered by the synchronize that added
No inline findings to post. |
Follow-up review (second commit)My prior review here covered the first commit (advisory fixes + gate raise + the regression test). This commit fixes a real gap it exposed: Verified independently:
The rest of my earlier review stands unchanged (the two minor/non-blocking notes — the "six" vs. 7-GHSA-ID count in the deploy.yml/test docstring, and the No new concerns. This looks ready to merge, with AC4 (verifying a real deploy succeeds at the raised threshold) deliberately left as a post-merge check per the PR description, which is a reasonable call given |
Closes #1131.
Both halves, in the order the issue requires
The issue is explicit that these must move together: raising the gate first blocks every deploy, fixing only the advisories leaves the gate blind next time.
1. All four advisories — fixed, not accepted
Every one had
fixAvailable: truewith an emptyeffectsarray, sonpm audit fixresolved them inside the existing major versions. There is therefore no allowlist entry and no review date: an allowlist would be a record of a risk nobody is taking.brace-expansionjs-yamlnanoid@babel/coreOnly
package-lock.jsonchanged — nopackage.jsonedit, no major bumps.2. The gate rises to
highBoth deploy jobs:
npm audit --audit-level=critical→--audit-level=high, with the reason inline. The tradeoff is stated rather than discovered later: audit results change without a code change, so a newly published high can block a deploy. That is the gate doing its job — six highs accumulated unnoticed undercritical.The decision is recorded where it survives
tests/test_deploy_audit_gate_1131.pycarries it — the four advisories, the fix-don't-accept reasoning, and why there is no allowlist — because the issue asks for something durable and a PR comment is not. It also asserts:high, expressed as a floor so tightening stays allowedOne thing I got wrong, and how I caught it
That last table was green theatre on the first pass. I set the floors from the advisories' "patched in" versions — which the pre-fix lockfile already satisfied, so every assertion passed against the broken state. The floors now come from the shipped lockfile, and I verified in the failing direction:
AC4 can only be checked after merge — deliberately
"Verify a deploy still succeeds with the raised threshold." The deploy does
git reset --hard origin/mainon the box and thennpm ci, so a deploy from this branch would audit main's lockfile, which still carries the three highs — it would fail, and would tell us nothing about this change.So the sequence is: merge, then the automatic push-to-main deploy is the verification. I will report that run on this PR and fix forward if it fails. Staging has no users.
Note taken from the issue
None of these four had one. That is the reason they were still open.