fix(deps): transitive nanoid, and a pre-push gate that asks the registry directly - #304
Merged
important-new merged 2 commits intoAug 8, 2026
Merged
Conversation
…7h3g-55p8) High severity, published 2026-07-29 and still unflagged by Dependabot on this repository ten days later — found by asking the registry directly rather than reading the alert count. It arrives via vite -> postcss. `npm update` rather than an override, deliberately: this repo also has a DIRECT nanoid@5.1.16, and a blanket `"nanoid"` override would drag that one down to the v3 line. postcss's range is a caret, so the transitive copy moves on its own. Lockfile touched in place; linux entries 346 -> 346. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0185QebqzFLviQKtnEjLkC3H
…e alert count lags
Dependabot is a server-side scan and its scan lags the advisory. Measured against
this project's own alerts on 2026-08-08:
dompurify advisory 2026-08-07 15:30Z -> alert 08-08 00:01Z (8.5 hours)
nanoid advisory 2026-07-29 15:31Z -> alert 08-08 00:18Z (10 days)
So a release that reads "Dependabot: 0 open" is reading "GitHub has not scanned
this yet". On the same day `npm audit` reported a HIGH advisory in two of three
repositories while both showed zero open alerts. This gate closes that window.
It runs on EVERY push and is deliberately NOT gated on package-lock.json moving:
an advisory is published against code already sitting in the lockfile, so
"nothing changed" is precisely the case it exists to catch.
The gate is built to fail rather than to pass when it cannot see:
- a transport error, a timeout, or an endpoint that does not implement audit
is a FAILURE, never a clean result;
- the report must account for a non-zero dependency count, because an audit
that examined nothing and an audit that found nothing produce the same
emptiness;
- the registry is pinned to registry.npmjs.org. This is not decoration: the
machine this was written on resolves to a mirror that answers
/-/npm/v1/security/* with "[NOT_IMPLEMENTED]", so an unpinned audit silently
checks nothing at all.
Proven in both directions before being wired in, per this project's rule that a
gate must be shown to go red. Against the pre-fix lockfile it names the package,
range, advisory URL and the fact that it is transitive; against the fixed one it
reports 1013 dependencies checked and exits 0; against the mirror it FAILS
instead of passing. The first attempt failed for the WRONG reason — spawning
npm.cmd without a shell is EINVAL on Windows, which would have red-flagged every
push on this machine, and red for the wrong reason is no better than green for
the wrong reason.
`SKIP_ADVISORY_AUDIT=1` exists for a genuine outage and announces itself loudly.
Manual run: `npm run lint:advisories`.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0185QebqzFLviQKtnEjLkC3H
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two commits: the advisory itself, and the gate that found it.
The advisory
nanoid <3.3.17(high, GHSA-2v37-7h3g-55p8), reached viavite -> postcss.Published 2026-07-29 and still unflagged by Dependabot on this repository ten
days later.
npm updaterather than an override, deliberately: this repo also carries adirect
nanoid@5.1.16, and a blanket"nanoid"override would drag that onedown to the v3 line. postcss's range is a caret, so the transitive copy moves on
its own. Lockfile touched in place; linux entries 346 -> 346.
Why a gate, given Dependabot exists
Dependabot is a server-side scan, and its scan lags the advisory. Measured
against this project's own alerts:
So a release reading "Dependabot: 0 open" is reading "GitHub has not looked
yet". Asked directly the same day,
npm auditreported a HIGH advisory in twoof three sibling repositories while both showed zero open alerts.
scripts/check-advisories.mjsruns at pre-push and is not gated onpackage-lock.jsonmoving — an advisory is published against code alreadysitting in the lockfile, so "nothing changed" is exactly the case it must catch.
It is built to fail rather than pass when it cannot see
failure, never a clean result.
examined nothing and an audit that found nothing produce the same emptiness.
registry.npmjs.org. Not decoration — the machinethis was written on resolves to a mirror that answers
/-/npm/v1/security/*with
[NOT_IMPLEMENTED], so an unpinned audit checks nothing and looks clean.Proven both directions before wiring: RED on the pre-fix lockfile (naming package,
range, advisory URL, transitive), GREEN on the fixed one reporting
1013 dependencies checked, RED against the mirror.npm.cmdwithout a shell is EINVAL on Windows. Red for the wrong reason is no better than
green for the wrong reason; the registry argument is URL-validated now because it
reaches a shell.
SKIP_ADVISORY_AUDIT=1exists for a genuine outage and announces itself.Manual run:
npm run lint:advisories.Full suite green locally: lint (24 gates),
test:unit723/5236,test:web335/2232.🤖 Generated with Claude Code