What
The eight bundled example frontends each carry two lockfiles —
package-lock.json and bun.lock — but only the npm one is ever
installed by CI, and Dependabot's npm updater only ever rewrites the npm
one. The bun half therefore drifts silently, and a merged security bump
leaves the directory half-patched.
#1401 is the worked example. It bumped fast-uri 3.1.5 → 3.1.7 (two
waves of high-severity advisories: authority injection via an unvalidated
port, host confusion via IP-literal brackets, SSRF via IPv6 normalization
and repeated percent-decoding). After that merge:
| directory |
package-lock.json |
bun.lock |
examples/chat/frontend-angular |
3.1.7 ✅ |
3.1.0 ❌ |
examples/voice/frontend-angular |
3.1.7 ✅ |
3.1.2 ❌ |
Why nothing caught it
.github/workflows/examples.yml's frontend job installs with npm ci
(deliberately ci, not install, so a manifest/lockfile desync is an
error) and builds — from package-lock.json. Nothing anywhere installs
the example bun.lock files, so no gate can see them diverge. The
workflow header already documents the sibling failure mode that actually
happened (ts-pattern declared in six package.json files and missing
from all six package-lock.json files, unnoticed because nothing
installed them); this is the same class of defect, one lockfile over.
A second desync found while fixing it
Re-resolving the two bun lockfiles surfaced a pre-existing violation
unrelated to fast-uri: both package.json files declare
"overrides": {
"@hono/node-server": "^2.1.0",
"@modelcontextprotocol/sdk": "^1.30.0"
}
while the committed bun.lock pinned @hono/node-server@1.19.14 and
@modelcontextprotocol/sdk@1.29.0 — i.e. the lockfile contradicted the
declared override. package-lock.json had already resolved them
correctly (2.1.0 / 1.30.0), which is further evidence that the bun half
is the unmaintained one.
Fix
Immediate: sync both bun.lock files (bun update fast-uri --lockfile-only in each directory), which also records the overrides and
converges the two lockfiles.
Structural (the part worth discussing): the drift can recur on the next
Dependabot bump. Options, roughly in increasing cost —
- Add a
bun install --frozen-lockfile leg to the frontend matrix, so
a desynced example bun.lock is a red check rather than an invisible
one. Cheapest, and it mirrors what the npm leg already does.
- Drop the example
bun.lock files entirely and let the frontends be
npm-only, since that is what CI and the documented build path use.
- Keep both and add a periodic sync job.
(1) or (2) both close the gap; (3) does not, it only shortens the window.
Refs #1401. Related: #779 (the same package is vulnerable in the root
bun.lock through fastify > fast-json-stringify > ajv, inside the
runtime closure — a separate and worse exposure that Dependabot is blind
to by design).
What
The eight bundled example frontends each carry two lockfiles —
package-lock.jsonandbun.lock— but only the npm one is everinstalled by CI, and Dependabot's npm updater only ever rewrites the npm
one. The bun half therefore drifts silently, and a merged security bump
leaves the directory half-patched.
#1401 is the worked example. It bumped
fast-uri3.1.5 → 3.1.7 (twowaves of high-severity advisories: authority injection via an unvalidated
port, host confusion via IP-literal brackets, SSRF via IPv6 normalization
and repeated percent-decoding). After that merge:
package-lock.jsonbun.lockexamples/chat/frontend-angularexamples/voice/frontend-angularWhy nothing caught it
.github/workflows/examples.yml'sfrontendjob installs withnpm ci(deliberately
ci, notinstall, so a manifest/lockfile desync is anerror) and builds — from
package-lock.json. Nothing anywhere installsthe example
bun.lockfiles, so no gate can see them diverge. Theworkflow header already documents the sibling failure mode that actually
happened (
ts-patterndeclared in sixpackage.jsonfiles and missingfrom all six
package-lock.jsonfiles, unnoticed because nothinginstalled them); this is the same class of defect, one lockfile over.
A second desync found while fixing it
Re-resolving the two bun lockfiles surfaced a pre-existing violation
unrelated to
fast-uri: bothpackage.jsonfiles declarewhile the committed
bun.lockpinned@hono/node-server@1.19.14and@modelcontextprotocol/sdk@1.29.0— i.e. the lockfile contradicted thedeclared override.
package-lock.jsonhad already resolved themcorrectly (2.1.0 / 1.30.0), which is further evidence that the bun half
is the unmaintained one.
Fix
Immediate: sync both
bun.lockfiles (bun update fast-uri --lockfile-onlyin each directory), which also records the overrides andconverges the two lockfiles.
Structural (the part worth discussing): the drift can recur on the next
Dependabot bump. Options, roughly in increasing cost —
bun install --frozen-lockfileleg to thefrontendmatrix, soa desynced example
bun.lockis a red check rather than an invisibleone. Cheapest, and it mirrors what the npm leg already does.
bun.lockfiles entirely and let the frontends benpm-only, since that is what CI and the documented build path use.
(1) or (2) both close the gap; (3) does not, it only shortens the window.
Refs #1401. Related: #779 (the same package is vulnerable in the root
bun.lockthroughfastify > fast-json-stringify > ajv, inside theruntime closure — a separate and worse exposure that Dependabot is blind
to by design).