GHSA-hm7r-c7qw-ghp6

Suggest an improvement
Source
https://github.com/advisories/GHSA-hm7r-c7qw-ghp6
Import Source
https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/04/GHSA-hm7r-c7qw-ghp6/GHSA-hm7r-c7qw-ghp6.json
JSON Data
https://api.osv.dev/v1/vulns/GHSA-hm7r-c7qw-ghp6
Aliases
Published
2026-04-03T22:01:25Z
Modified
2026-04-06T23:49:39Z
Severity
  • 7.5 (High) CVSS_V3 - CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N CVSS Calculator
Summary
fast-jwt accepts unknown `crit` header extensions (RFC 7515 violation)
Details

Summary

fast-jwt does not validate the crit (Critical) Header Parameter defined in RFC 7515 §4.1.11. When a JWS token contains a crit array listing extensions that fast-jwt does not understand, the library accepts the token instead of rejecting it. This violates the MUST requirement in the RFC.


RFC Requirement

RFC 7515 §4.1.11:

If any of the listed extension Header Parameters are not understood and supported by the recipient, then the JWS is invalid.


Proof of Concept

const { createSigner, createVerifier } = require("fast-jwt"); // v3.3.3

const signer = createSigner({ key: "secret", algorithm: "HS256" });
const token = signer({
  sub: "attacker",
  role: "admin",
  header: { crit: ["x-custom-policy"], "x-custom-policy": "require-mfa" },
});

// Should REJECT — x-custom-policy is not understood
const verifier = createVerifier({ key: "secret", algorithms: ["HS256"] });
try {
  const result = verifier(token);
  console.log("ACCEPTED:", result);
  // Output: ACCEPTED: { sub: 'attacker', role: 'admin' }
} catch (e) {
  console.log("REJECTED:", e.message);
}

Expected: Error — unsupported critical extension Actual: Token accepted.

Comparison

// jose (panva) v4+ — correctly rejects
const jose = require("jose");
await jose.jwtVerify(token, new TextEncoder().encode("secret"));
// throws: Extension Header Parameter "x-custom-policy" is not recognized

Impact

  • Split-brain verification in mixed-library environments
  • Security policy bypass when crit carries enforcement semantics
  • Token binding bypass (RFC 7800 cnf confirmation)
  • See CVE-2025-59420 for full impact analysis

Suggested Fix

In src/verifier.js, add crit validation after header decoding:

const SUPPORTED_CRIT = new Set(["b64"]);

function validateCrit(header) {
  if (!header.crit) return;
  if (!Array.isArray(header.crit) || header.crit.length === 0)
    throw new Error("crit must be a non-empty array");
  for (const ext of header.crit) {
    if (!SUPPORTED_CRIT.has(ext))
      throw new Error(`Unsupported critical extension: ${ext}`);
    if (!(ext in header))
      throw new Error(`Critical extension ${ext} not present in header`);
  }
}
Database specific
{
    "cwe_ids":  [
        "CWE-345",
        "CWE-636"
    ],
    "github_reviewed":  true,
    "github_reviewed_at":  "2026-04-03T22:01:25Z",
    "nvd_published_at":  "2026-04-06T17:17:13Z",
    "severity":  "HIGH"
}
References

Affected packages

npm / fast-jwt

Package

Affected ranges

Type
SEMVER
Events
Introduced
0 Unknown introduced version / All previous versions are affected
Last Affected
6.1.0

Database specific

source
"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2026/04/GHSA-hm7r-c7qw-ghp6/GHSA-hm7r-c7qw-ghp6.json"