Skip to content

v2.72.1: the vulnerability mail said nothing could be fixed, and an expired session went unnoticed

Choose a tag to compare

@gitayg gitayg released this 13 Sep 06:32
· 38 commits to main since this release

v2.72.1: the vulnerability mail said nothing could be fixed, and an expired session went unnoticed

EVERY FINDING SAID "NO FIXED VERSION PUBLISHED". The live fleet report held 280
findings, and 280 of them had fixed = null. Not most — all. The scanner asks
OSV's /v1/querybatch, which returns {id, modified} per advisory and nothing
else; fixedVersionFor walked vuln.affected[].ranges[].events[].fixed on data
that has no affected at all, and returned null every time since the feature
shipped. react-router-dom@6.30.3 is fixed in 6.30.6, a patch bump, and was
mailed as unfixable. The contract says a null means there is nothing to upgrade
to, so the daily digest was actively discouraging the one action that works.

Discovery stays on querybatch; the distinct advisory ids are then hydrated from
GET /v1/vulns/. Bounded and cheap — 122 distinct ids behind 280 findings
across the whole fleet. A hydration failure records the scan as an error, NOT
as fixed = null: "we could not find out" must never render as "there is nothing
to upgrade to", which is this bug's exact shape.

It survived a full test suite because the fixtures handed fixedVersionFor
advisory objects WITH affected — a response the real endpoint never returns.
The lockfile test's stub now serves both endpoints and asserts a real fixed
version comes back through them.

AN EXPIRED SESSION WENT UNNOTICED. Three surfaces, three different failures.
The admin SPA redirected only when a 401 body matched one of five known
messages; the server has twelve, so Token expired matched nothing and nothing
happened. Inverted: a 401 from a session-gated route bounces to sign-in, and the
login routes are excluded — a wrong password is the sign-in screen's own answer,
and redirecting there is a loop. api.ts, behind AppStudio's agent chat, had no
401 handling at all. And the SSE panel reconnected on every error with no delay,
no session check and no close of the replacement — an expired session became a
silent loop leaking EventSources forever. It now probes the session first, backs
off, and stops. A latch makes simultaneous refusals one bounce, not one per
poller. Design borrowed from hub UI v1.122.1, which hit the same failure.

Known: tcp-ingress-deploy-gate.test.js flakes about one run in four on a
managed-source app this change does not reach; unchanged since v2.42.0.