Skip to content

fix(agentex-ui): bump nanoid 3.3.16 -> 3.3.18 (CVE-2026-67213) - #398

Open
scale-prodsec[bot] wants to merge 1 commit into
mainfrom
security-bot/gfdvr-23886-trivy-remediate-nanoid3316-vulnerabilities
Open

fix(agentex-ui): bump nanoid 3.3.16 -> 3.3.18 (CVE-2026-67213)#398
scale-prodsec[bot] wants to merge 1 commit into
mainfrom
security-bot/gfdvr-23886-trivy-remediate-nanoid3316-vulnerabilities

Conversation

@scale-prodsec

@scale-prodsec scale-prodsec Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Remediates CVE-2026-67213 (HIGH) in nanoid for the agentex-ui service.

Package nanoid (npm)
Version 3.3.16 -> 3.3.18
CVE CVE-2026-67213 (HIGH)
Service / dir agentex-ui
Relationship transitivepostcss@8.5.25 -> nanoid
Linear GFDVR-23886 (child GFDVR-23887)

nanoid before 3.3.17 / 5.1.6 enters an infinite loop when customAlphabet() or
customRandom() is called with size = 0 — the generation loop never reaches its exit
condition. Availability impact where the size is attacker-influenced.

Why the 3.x line and not 5.1.6

The advisory lists two fixed versions (3.3.17, 5.1.6). 3.3.x is the correct target here:
postcss imports nanoid as CommonJS — require('nanoid/non-secure')
(postcss/lib/input.js:3) — and
nanoid 5.x is ESM-only ("type": "module"). Pinning 5.1.6 would resolve cleanly and then
break postcss at runtime. Staying same-major keeps this a lockfile-only change.

Applied through the existing overrides block, the convention already used in this
manifest for exactly this purpose (cross-spawn, postcss, sharp, tar). The floor is
^3.3.17 (the advisory's fixed version); every version that range can select is
advisory-clean, and it resolved to the latest such release, 3.3.18.

Version gate

  • OSV for nanoid@3.3.17 and @3.3.18: zero known advisories.
  • Satisfies postcss's declared nanoid: ^3.3.16, so no constraint is violated.
  • engines: node ^10 || ^12 || ^13.7 || ^14 || >=15.0.1 — compatible with node 20 (Dockerfile + CI).

Behavior contract (every version crossed)

Read both releases crossed, not just the endpoints:

  • 3.3.17 — the security fix. Source diff vs 3.3.16 is exactly one line: if (size <= 0) return ''.
    The prior behavior was an infinite hang, so no caller can depend on it. No change to error types,
    return shapes, defaults, or coercions.
  • 3.3.18 — only async/index.native.js (React Native infinite-loop fix) + README. Core
    index.cjs is byte-identical to 3.3.17; inert for a Next.js server/browser target.
  • nanoid/non-secure — the only entry point postcss uses — is byte-identical across 3.3.16 -> 3.3.18.
  • Target declares no dependencies and no peerDependencies, so the transitive closure is nanoid alone.
  • No first-party code in agentex-ui imports nanoid, customAlphabet, or customRandom.

Upstream tracker sweep: ai/nanoid#605 is this exact
CVE, closed as fixed by 3.3.17. No open regression/breaking issues against 3.3.17 or 3.3.18.

Validation

All run locally with npm 10.9.4 / node 20 parity (matching agentex-ui/Dockerfile and the
CI workflow) — not the sandbox default npm 12:

  • npm ci — passes, lockfile internally consistent and not rewritten (the exact CI + Docker gate)
  • npm ls nanoid --all — single instance: nanoid@3.3.18 overridden
  • npm run typecheck (CI job) — clean
  • npm run lint (CI job) — no ESLint warnings or errors
  • npm run test:run75/75 tests pass (11 files)
  • npm run build — full production build succeeds, all 10 routes generated (exercises postcss/Tailwind)
  • Direct CVE repro: customAlphabet('abcdef',10)(0) and customRandom(...)(0) now return ""
    in ~1ms instead of hanging; normal 10-char generation unaffected
  • Consumer smoke: postcss.parse() works, nanoid/non-secure export intact

Diff scope

Two files, +4/-3. Exactly one lockfile package entry changed (node_modules/nanoid);
byte-compared the before/after lock to confirm no other entry differs. lockfileVersion stays
3, resolved stays on the public npm registry, no file-mode changes, no application-code
changes, no dependency additions or removals.

Note: regenerating with CI-parity npm 10 initially stripped the libc metadata field from four
@next/swc-linux-* optional binaries (npm 11+ emits it, npm 10 does not). That drift is unrelated
to this fix and would affect musl/glibc native-binary selection, so it was reverted — the final
diff carries the nanoid change only.

Greptile Summary

The PR raises the transitive nanoid version used by agentex-ui from 3.3.16 to 3.3.18 to remediate CVE-2026-67213.

  • Adds a ^3.3.17 nanoid override using the manifest’s existing override mechanism.
  • Updates the lockfile resolution and integrity metadata to nanoid 3.3.18.

Confidence Score: 5/5

The PR appears safe to merge with no actionable correctness, compatibility, or security regressions identified.

The override remains within postcss’s accepted nanoid 3.x range, the lockfile consistently resolves the patched version, and the repository’s Node and npm targets support the resulting dependency configuration.

Important Files Changed

Filename Overview
agentex-ui/package.json Adds a compatible nanoid security floor to the existing overrides block without changing application behavior.
agentex-ui/package-lock.json Resolves nanoid to 3.3.18 with dependency ranges and runtime constraints remaining consistent.

Reviews (1): Last reviewed commit: "fix(agentex-ui): bump nanoid 3.3.16 -> 3..." | Re-trigger Greptile

nanoid 3.3.16 hangs in an infinite loop when customAlphabet/customRandom
are called with size 0 (CVE-2026-67213, HIGH). Pin the transitive
dependency (via postcss -> nanoid) to the patched 3.3.x line using the
existing overrides block.

Stays on the 3.x line: postcss consumes nanoid via
require("nanoid/non-secure"), and nanoid 5.x is ESM-only, so 5.1.6 would
break the consumer.

Verified: npm ci, typecheck, lint, 75 tests, next build, and a direct
size-0 repro all pass.
@scale-prodsec
scale-prodsec Bot requested a review from a team as a code owner August 8, 2026 05:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants