node-forge GHSA-86w9-cpqp-85rv in Nuxt via listhen: no patched version exists, triage the npm audit block
Triages the npm audit block from node-forge GHSA-86w9-cpqp-85rv (CVE-2026-85393) in Nuxt apps, where node-forge arrives through nitropack and listhen and no patched release exists. Shows proving the chain, checking whether RSA signature verification is reachable, recording a time-boxed single-advisory audit exception, and optionally backporting the unmerged upstream fix with patch-package or pnpm patch. Use when audit or a scanner flags node-forge via listhen in a Nuxt project.
TL;DR
There is no version to upgrade to and no clean way to remove the package. As of 2026-10-12 the GitHub advisory GHSA-86w9-cpqp-85rv (CVE-2026-85393) lists node-forge at or below 1.4.0 as vulnerable with no first patched version, and 1.4.0 is still the latest release on npm. In a Nuxt app the chain is nuxt, then @nuxt/nitro-server, then nitropack, then listhen, then node-forge, and node-forge is a real listhen dependency (its HTTPS certificate work), not a stray lockfile entry. The working answers are: prove the vulnerable verification path is not reachable in your app, then either record a time-boxed audit exception with an expiry and a recheck trigger, or backport the unmerged upstream fix with patch-package or pnpm patch and pair it with the same exception, because scanners judge the version number and will keep flagging 1.4.0 either way. Do not run npm audit fix with the force flag and do not override node-forge to an older release: every published release is in the affected range.
node-forge
Severity: high
node-forge RSA PKCS#1 v1.5 signature verification accepts extra nested DigestAlgorithm elements - https://github.com/advisories/GHSA-86w9-cpqp-85rv
fix available via `npm audit fix --force`
listhen depends on vulnerable versions of node-forge
nitropack depends on vulnerable versions of listhenSteps
- Confirm the chain in your project. Run
npm ls node-forge listhen nitropack nuxt. Expected: a single path showing nuxt at the top, then nitropack, then listhen, then node-forge at 1.4.0. If node-forge also appears under other parents (Expo tooling, acme-client, and code-signing packages are common ones), triage each path separately; this skill covers the Nuxt and listhen path. - Confirm there is nothing to upgrade to. Run
npm view node-forge versionand check the advisory page. Expected: npm reports 1.4.0 as the latest version, and the advisory lists the affected range as at or below 1.4.0 with no patched version. An npm override cannot fix this, because an override needs a safe target version and none exists; overriding to any older 1.x or 0.x release stays inside the affected range. - Check reachability before accepting any risk. The flaw is in RSA PKCS#1 v1.5 signature verification: node-forge accepts extra nested DigestAlgorithm elements, so a forged signature made with a low-exponent RSA key can pass verification. Ask two questions. First, does your own code import node-forge and verify signatures or certificates from outside parties with it? Search the repo for node-forge imports outside node_modules. Second, what does listhen use it for? listhen loads node-forge for generating self-signed HTTPS certificates for the local development server; it creates and signs its own certificate and does not verify RSA signatures supplied by an attacker. Expected finding for a standard Nuxt app: no application code path verifies an attacker-supplied signature with node-forge, and listhen is exercised by the dev server, not by request handling in a production build. If your app does verify outside signatures with node-forge directly, stop: do not accept the risk, apply the patch in step 5, and treat it as release-blocking.
- Record a time-boxed audit exception, scoped to this one advisory. For pnpm, add the GHSA id under auditConfig ignoreGhsas in pnpm-workspace.yaml, with a comment naming the expiry date and the reason. For npm projects, use an allowlist tool such as audit-ci with GHSA-86w9-cpqp-85rv as the single allowlisted entry, or the equivalent single-advisory allowlist in your scanner (Trivy, Dependabot, or Snyk ignore with an expiry). Expected: the audit gate goes green for this advisory only, every other high or critical finding still fails the gate, and the exception carries an expiry 30 to 90 days out, not an open-ended ignore.
- Optional, for teams that cannot accept the unpatched code: backport the upstream fix. The digitalbazaar forge repository has an open, unmerged pull request, number 1152, that rejects the extra elements inside the DigestInfo DigestAlgorithm sequence during verification. With npm, edit the installed package under node_modules, run
npx patch-package node-forge, and commit the generated patch file plus a postinstall hook that reapplies it. With pnpm, runpnpm patch node-forge@1.4.0, apply the same change, thenpnpm patch-commitand commit the result. Add a regression test that feeds a signature with extra nested DigestAlgorithm elements and asserts verification rejects it, while a valid signature still verifies. Expected: the test fails on the stock 1.4.0 install and passes with the patch. Note that scanners still flag version 1.4.0 after patching, so keep the step 4 exception and annotate it as patched locally. - Set the removal trigger now, while it is cheap. The exception and any local patch come out when one of these happens: a node-forge release above 1.4.0 ships with the fix, listhen releases a version that drops or upgrades node-forge, or Nuxt and nitropack update the listhen range. Recheck on the exception expiry date with
npm view node-forge versionandnpm outdated listhen nitropack nuxt. Expected after a real fix ships: update the chain, delete the exception and the patch file, andnpm auditreports no GHSA-86w9-cpqp-85rv finding. - Tell the security reviewer the right story in the pull request: this is an accepted, expiring exception for an advisory with no patched release, on a dependency whose vulnerable function is not reachable in the app, with the upstream fix tracked. Link the advisory and the upstream pull request. Expected: the reviewer can verify every claim in minutes instead of re-deriving that no upgrade exists.
When to use this skill
Use it when npm audit, pnpm audit, Dependabot, Trivy, or a CI security gate blocks on GHSA-86w9-cpqp-85rv or CVE-2026-85393 for node-forge in a Nuxt project, and the audit tree shows listhen and nitropack above node-forge. Also use it when a teammate proposes deleting node-forge, forcing the audit fix, or overriding the version and you need to show why none of those work yet.
When not to use this skill
Not for node-forge findings that arrive through a different parent where the vulnerable verification is actually called on outside data; that case needs the patch or a dependency change, not an exception alone. Not for the older node-forge advisories that do have patched releases (for example the ASN.1 issues fixed in 1.3.2 and later): upgrade instead. Not a reason to ignore future node-forge advisories; the exception covers exactly one GHSA id.
Variant phrasings
npm audit node-forge transitive dependency listhen
Same chain and same answer: the transitive path through listhen is the finding, and the triage above applies unchanged.
Nuxt security scan reports vulnerable transitive dependencies
Nuxt closed its tracking issue for these transitive findings as not planned, because the fix has to land in node-forge and listhen first. Treat it in the app, with the exception or patch above, rather than waiting on a Nuxt release.
Can I just remove listhen or node-forge from a Nuxt app
No supported removal exists while you keep the standard Nuxt and Nitro dev server: listhen declares node-forge as a regular dependency, so package-manager removal, manual lockfile edits, and empty overrides either regenerate on install or break listhen. Removing the whole Nuxt toolchain removes it, which is a migration decision, not an audit fix.
Why it happens
The advisory, published 2026-09-03, is an incomplete-fix follow-up: node-forge failed to validate the element count inside nested DigestAlgorithm sequences during RSA PKCS#1 v1.5 signature verification, so garbage bytes can be embedded and signatures forged against low-exponent keys. Every release up to and including the latest, 1.4.0, is affected, and the upstream fix exists only as an open pull request. Framework trees surface it instantly because nitropack depends on listhen and listhen depends on node-forge, so one unpatched leaf turns the whole Nuxt audit red, and npm counts the finding once per package on the path.
Edge cases and pitfalls
- npm audit fix with the force flag: npm may offer to install a different major of an unrelated parent package; that change still ships node-forge 1.4.0 in most trees and adds a breaking migration on top. Read the offered install line before ever accepting it.
- Deleting the node_modules folder or hand-editing the lockfile: both regenerate on the next install and can break the dev server HTTPS path. Not a fix.
- Blanket audit ignores: an ignore with no GHSA scoping, no expiry, and no owner will silently cover the next, reachable node-forge flaw too. Scope it to the single advisory.
- Production-only audit runs: whether listhen shows up depends on where nuxt sits in your manifest (often devDependencies in app projects). A clean production audit does not clear a scanner that reads the full lockfile; align the exception with the tool that is actually blocking.
- Assuming the exception is the fix: it is a documented acceptance. The fix is a patched upstream release, and the expiry date is what forces the recheck.
Compatibility
Verified 2026-10-12 against the live npm registry and GitHub advisory database: node-forge latest 1.4.0 (affected at or below 1.4.0, no patched version), listhen 1.10.1 declaring node-forge ^1.4.0, nitropack 2.13.4 depending on listhen, and nuxt 4.6.1 shipping @nuxt/nitro-server on nitropack 2.13.4. Applies to npm and pnpm projects on Nuxt 3 and 4 whose tree contains the same chain. Re-verify the version facts before reusing after a new node-forge release ships.