CVE-2026-107724
fast-jwt treats raw public JWK JSON as an HMAC secret, enabling HS256 token forgery
fast-jwt provides fast JSON Web Token (JWT) implementation. In 6.2.4, fast-jwt can classify raw serialized public JWK or JWKS JSON as an HMAC secret because src/crypto.js performDetectPublicKeyAlgorithms treats non-PEM strings as symmetric key material. If HS256 is explicitly allowed or inferred, an attacker who knows the exact serialized public-key bytes can use those bytes as an HMAC key and create a token containing arbitrary claims that createVerifier accepts. Serialization ordering or whitespace differences can prevent exploitation, and applications using supported PEM keys with an asymmetric-only algorithm allowlist are not affected. This issue is fixed in version 6.3.0.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- High
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- High
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
7.4
fast-jwt treats raw public JWK JSON as an HMAC secret, enabling HS256 token forgery
fast-jwt provides fast JSON Web Token (JWT) implementation. In 6.2.4, fast-jwt can classify raw serialized public JWK or JWKS JSON as an HMAC secret because src/crypto.js performDetectPublicKeyAlgorithms treats non-PEM strings as symmetric key material. If HS256 is explicitly allowed or inferred, an attacker who knows the exact serialized public-key bytes can use those bytes as an HMAC key and create a token containing arbitrary claims that createVerifier accepts. Serialization ordering or whitespace differences can prevent exploitation, and applications using supported PEM keys with an asymmetric-only algorithm allowlist are not affected. This issue is fixed in version 6.3.0.
- Record
CVE-2026-107724- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N - Weakness
- CWE-347
- Updated
- 2026-11-02
EUVDEUVD-2026-95312
7.4
fast-jwt provides fast JSON Web Token (JWT) implementation. In 6.2.4, fast-jwt can classify raw serialized public JWK or JWKS JSON as an HMAC secret because src/crypto.js performDetectPublicKeyAlgorithms treats non-PEM strings as symmetric key material. If HS256 is explicitly allowed or inferred, an attacker who knows the exact serialized public-key bytes can use those bytes as an HMAC key and create a token containing arbitrary claims that createVerifier accepts. Serialization ordering or whitespace differences can prevent exploitation, and applications using supported PEM keys with an asymmetric-only algorithm allowlist are not affected. This issue is fixed in version 6.3.0.
- Record
EUVD-2026-95312- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-g3jj-5cmm-3hxx
7.4
fast-jwt treats raw public JWK JSON as an HMAC secret, enabling HS256 token forgery
Summary
fast-jwt 6.2.4 silently classifies raw serialized public JWK JSON
as an HMAC secret.
If an application supplies public JWK JSON text as the verifier key and
HS256 is explicitly allowed or automatically inferred, an attacker who
knows the same public JSON text can use it as an HMAC key and create an
arbitrary HS256 token that fast-jwt accepts as valid.
This can result in authentication or authorization bypass through forged JWT claims.
The PoC demonstrates the issue with a serialized RSA public JWK. The same non-PEM classification also applies to raw JWKS JSON text, although the attached standalone PoC focuses on the smallest JWK case.
Details
The verifier accepts a string or Buffer as key material. In
src/crypto.js, performDetectPublicKeyAlgorithms() attempts to infer
the permitted algorithm family from the supplied string.
Strings matching supported PEM public-key formats are classified as asymmetric keys. Any other non-empty string is assumed to be an HMAC secret:
function performDetectPublicKeyAlgorithms(key) {
const trimmedKey = key.trim()
const publicKeyPemMatch = trimmedKey.match(publicKeyPemMatcher)
if (trimmedKey.match(privateKeyPemMatcher)) {
throw new TokenError(
TokenError.codes.invalidKey,
'Private keys are not supported for verifying.'
)
} else if (
publicKeyPemMatch &&
publicKeyPemMatch[1] === 'RSA'
) {
return rsaAlgorithms
} else if (
!publicKeyPemMatch &&
!trimmedKey.includes(publicKeyX509CertMatcher)
) {
// Not a PEM, assume a plain secret
return hsAlgorithms
}
// ...
}
A serialized RSA, EC, or OKP public JWK is valid JSON, but it is not PEM
and does not contain a certificate header. It therefore reaches:
return hsAlgorithms
The HS256 verification path then uses the complete public JSON string as
the HMAC key.
Because JWK public-key material is public by design, an attacker can know
the verifier's cryptographic key material. When that public material is
reinterpreted as an HMAC secret, the attacker can calculate a valid
HS256 signature over arbitrary claims.
The vulnerable transition is:
Public asymmetric JWK JSON
|
v
Does not match PEM detection
|
v
Classified as a plain secret
|
v
HS256 permitted or inferred
|
v
Attacker signs using public JSON bytes
|
v
Forged token accepted
The attached PoC demonstrates both relevant configurations:
An explicit mixed-family allowlist:
createVerifier({
key: rawJwk,
algorithms: ['HS256', 'RS256']
})
No explicit algorithm allowlist:
createVerifier({
key: rawJwk
})
In the second configuration, fast-jwt detects the raw non-PEM string as
symmetric key material and permits the HS algorithm family.
An RS256-only verifier rejects the same forged token, providing a
negative control:
createVerifier({
key: rawJwk,
algorithms: ['RS256']
})
The documentation describes asymmetric verifier keys as PEM-encoded
public keys. The security issue is not that the raw JWK is successfully
parsed as an asymmetric key. It is that ambiguous structured public-key
text is silently reclassified as a symmetric secret rather than being
rejected, and that this classification permits an attacker-controlled
HS256 token.
PoC
Requirements:
Node.js 20 or newer
npm
The attached submission ZIP
Extract the attachment and run:
cd poc
npm install
node poc.js
The PoC performs the following steps:
Generates a fresh RSA key pair locally.
Exports only the public key as a JWK.
Adds ordinary public JWK metadata such as kid, use, and alg.
Serializes the public JWK as JSON.
Uses the serialized public JWK text as an HS256 HMAC key.
Creates a token containing attacker-selected administrative claims.
Supplies the same raw public JSON string to the real
fast-jwt verifier.
Confirms acceptance with a mixed HS256/RS256 allowlist.
Confirms acceptance when algorithm detection is left enabled.
Confirms rejection with an…
- Record
GHSA-g3jj-5cmm-3hxx- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N - Weakness
- CWE-347
- Updated
- 2026-11-02
NVD
7.4
fast-jwt provides fast JSON Web Token (JWT) implementation. In 6.2.4, fast-jwt can classify raw serialized public JWK or JWKS JSON as an HMAC secret because src/crypto.js performDetectPublicKeyAlgorithms treats non-PEM strings as symmetric key material. If HS256 is explicitly allowed or inferred, an attacker who knows the exact serialized public-key bytes can use those bytes as an HMAC key and create a token containing arbitrary claims that createVerifier accepts. Serialization ordering or whitespace differences can prevent exploitation, and applications using supported PEM keys with an asymmetric-only algorithm allowlist are not affected. This issue is fixed in version 6.3.0.
- Record
CVE-2026-107724- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N - Weakness
- CWE-347
- Updated
- 2026-11-02
OSV
7.4
fast-jwt treats raw public JWK JSON as an HMAC secret, enabling HS256 token forgery
fast-jwt provides fast JSON Web Token (JWT) implementation. In 6.2.4, fast-jwt can classify raw serialized public JWK or JWKS JSON as an HMAC secret because src/crypto.js performDetectPublicKeyAlgorithms treats non-PEM strings as symmetric key material. If HS256 is explicitly allowed or inferred, an attacker who knows the exact serialized public-key bytes can use those bytes as an HMAC key and create a token containing arbitrary claims that createVerifier accepts. Serialization ordering or whitespace differences can prevent exploitation, and applications using supported PEM keys with an asymmetric-only algorithm allowlist are not affected. This issue is fixed in version 6.3.0.
- Record
CVE-2026-107724- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N - Weakness
- CWE-347
- Updated
- 2026-11-02
OSVGHSA-g3jj-5cmm-3hxx
7.4
fast-jwt treats raw public JWK JSON as an HMAC secret, enabling HS256 token forgery
Summary
fast-jwt 6.2.4 silently classifies raw serialized public JWK JSON
as an HMAC secret.
If an application supplies public JWK JSON text as the verifier key and
HS256 is explicitly allowed or automatically inferred, an attacker who
knows the same public JSON text can use it as an HMAC key and create an
arbitrary HS256 token that fast-jwt accepts as valid.
This can result in authentication or authorization bypass through forged JWT claims.
The PoC demonstrates the issue with a serialized RSA public JWK. The same non-PEM classification also applies to raw JWKS JSON text, although the attached standalone PoC focuses on the smallest JWK case.
Details
The verifier accepts a string or Buffer as key material. In
src/crypto.js, performDetectPublicKeyAlgorithms() attempts to infer
the permitted algorithm family from the supplied string.
Strings matching supported PEM public-key formats are classified as asymmetric keys. Any other non-empty string is assumed to be an HMAC secret:
function performDetectPublicKeyAlgorithms(key) {
const trimmedKey = key.trim()
const publicKeyPemMatch = trimmedKey.match(publicKeyPemMatcher)
if (trimmedKey.match(privateKeyPemMatcher)) {
throw new TokenError(
TokenError.codes.invalidKey,
'Private keys are not supported for verifying.'
)
} else if (
publicKeyPemMatch &&
publicKeyPemMatch[1] === 'RSA'
) {
return rsaAlgorithms
} else if (
!publicKeyPemMatch &&
!trimmedKey.includes(publicKeyX509CertMatcher)
) {
// Not a PEM, assume a plain secret
return hsAlgorithms
}
// ...
}
A serialized RSA, EC, or OKP public JWK is valid JSON, but it is not PEM
and does not contain a certificate header. It therefore reaches:
return hsAlgorithms
The HS256 verification path then uses the complete public JSON string as
the HMAC key.
Because JWK public-key material is public by design, an attacker can know
the verifier's cryptographic key material. When that public material is
reinterpreted as an HMAC secret, the attacker can calculate a valid
HS256 signature over arbitrary claims.
The vulnerable transition is:
Public asymmetric JWK JSON
|
v
Does not match PEM detection
|
v
Classified as a plain secret
|
v
HS256 permitted or inferred
|
v
Attacker signs using public JSON bytes
|
v
Forged token accepted
The attached PoC demonstrates both relevant configurations:
An explicit mixed-family allowlist:
createVerifier({
key: rawJwk,
algorithms: ['HS256', 'RS256']
})
No explicit algorithm allowlist:
createVerifier({
key: rawJwk
})
In the second configuration, fast-jwt detects the raw non-PEM string as
symmetric key material and permits the HS algorithm family.
An RS256-only verifier rejects the same forged token, providing a
negative control:
createVerifier({
key: rawJwk,
algorithms: ['RS256']
})
The documentation describes asymmetric verifier keys as PEM-encoded
public keys. The security issue is not that the raw JWK is successfully
parsed as an asymmetric key. It is that ambiguous structured public-key
text is silently reclassified as a symmetric secret rather than being
rejected, and that this classification permits an attacker-controlled
HS256 token.
PoC
Requirements:
Node.js 20 or newer
npm
The attached submission ZIP
Extract the attachment and run:
cd poc
npm install
node poc.js
The PoC performs the following steps:
Generates a fresh RSA key pair locally.
Exports only the public key as a JWK.
Adds ordinary public JWK metadata such as kid, use, and alg.
Serializes the public JWK as JSON.
Uses the serialized public JWK text as an HS256 HMAC key.
Creates a token containing attacker-selected administrative claims.
Supplies the same raw public JSON string to the real
fast-jwt verifier.
Confirms acceptance with a mixed HS256/RS256 allowlist.
Confirms acceptance when algorithm detection is left enabled.
Confirms rejection with an…
- Record
GHSA-g3jj-5cmm-3hxx- CVSS 3.1
- 7.4 High
CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N - Weakness
- CWE-347
- Updated
- 2026-11-02
Affected products
Affected packages
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-107724 is a high vulnerability (CVSS 7.4) in Nearform Fast-jwt, published October 8, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.28%, the 20th percentile. Fixed in fast-jwt 6.3.0.
References
github.com/nearform/fast-jwt/security/advisories/GHSA-g3jj-5cmm-3hxx
github.com/nearform/fast-jwt/pull/636
github.com/nearform/fast-jwt/commit/10f9591349199ed2ab9fa1748ce92cdca697f6cf
github.com/nearform/fast-jwt/releases/tag/v6.3.0
github.com/advisories/GHSA-g3jj-5cmm-3hxx
github.com/CVEProject/cvelistV5/tree/main/cves/2026/107xxx/CVE-2026-107724.json
nvd.nist.gov/vuln/detail/CVE-2026-107724
github.com/nearform/fast-jwt
Left out here: the rest of 2 source descriptions. The JSON record has them.