CVE-2026-25537
jsonwebtoken has Type Confusion that leads to potential authorization bypass
jsonwebtoken is a JWT lib in rust. Prior to version 10.3.0, there is a Type Confusion vulnerability in jsonwebtoken, specifically, in its claim validation logic. When a standard claim (such as nbf or exp) is provided with an incorrect JSON type (Like a String instead of a Number), the library’s internal parsing mechanism marks the claim as “FailedToParse”. Crucially, the validation logic treats this “FailedToParse” state identically to “NotPresent”. This means that if a check is enabled (like: validate_nbf = true), but the claim is not explicitly marked as required in required_spec_claims, the library will skip the validation check entirely for the malformed claim, treating it as if it were not there. This allows attackers to bypass critical time-based security restrictions (like “Not Before” checks) and commit potential authentication and authorization bypasses. This issue has been patched in version 10.3.0.
Attack profile
How easy it is to exploit
- Attack vector
- Network
- Complexity
- Low
- Privileges needed
- None
- User interaction
- None
What an attacker can affect
- Confidentiality
- None
- Integrity
- Low
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used 5.5
jsonwebtoken has Type Confusion that leads to potential authorization bypass
jsonwebtoken is a JWT lib in rust. Prior to version 10.3.0, there is a Type Confusion vulnerability in jsonwebtoken, specifically, in its claim validation logic. When a standard claim (such as nbf or exp) is provided with an incorrect JSON type (Like a String instead of a Number), the library’s internal parsing mechanism marks the claim as “FailedToParse”. Crucially, the validation logic treats this “FailedToParse” state identically to “NotPresent”. This means that if a check is enabled (like: validate_nbf = true), but the claim is not explicitly marked as required in required_spec_claims, the library will skip the validation check entirely for the malformed claim, treating it as if it were not there. This allows attackers to bypass critical time-based security restrictions (like “Not Before” checks) and commit potential authentication and authorization bypasses. This issue has been patched in version 10.3.0.
- Record
CVE-2026-25537- CVSS 4.0
- 5.5 Medium
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:P - Weakness
- CWE-843
- Updated
- 2026-11-02
EUVDEUVD-2026-5334 5.5
jsonwebtoken is a JWT lib in rust. Prior to version 10.3.0, there is a Type Confusion vulnerability in jsonwebtoken, specifically, in its claim validation logic. When a standard claim (such as nbf or exp) is provided with an incorrect JSON type (Like a String instead of a Number), the library’s internal parsing mechanism marks the claim as “FailedToParse”. Crucially, the validation logic treats this “FailedToParse” state identically to “NotPresent”. This means that if a check is enabled (like: validate_nbf = true), but the claim is not explicitly marked as required in required_spec_claims, the library will skip the validation check entirely for the malformed claim, treating it as if it were not there. This allows attackers to bypass critical time-based security restrictions (like “Not Before” checks) and commit potential authentication and authorization bypasses. This issue has been patched in version 10.3.0.
- Record
EUVD-2026-5334- CVSS 4.0
- 5.5 Medium
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:P - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-h395-gr6q-cpjc 5.5
jsonwebtoken has Type Confusion that leads to potential authorization bypass
Summary:
It has been discovered that there is a Type Confusion vulnerability in jsonwebtoken, specifically, in its claim validation logic.
When a standard claim (such as nbf or exp) is provided with an incorrect JSON type (Like a String instead of a Number), the library’s internal parsing mechanism marks the claim as “FailedToParse”. Crucially, the validation logic treats this “FailedToParse” state identically to “NotPresent”.
This means that if a check is enabled (like: validate_nbf = true), but the claim is not explicitly marked as required in required_spec_claims, the library will skip the validation check entirely for the malformed claim, treating it as if it were not there. This allows attackers to bypass critical time-based security restrictions (like “Not Before” checks) and commit potential authentication and authorization bypasses.
Details:
The vulnerability stems from the interaction between the TryParse enum and the validate function in src/validation.rs.
- The TryParse Enum: The library uses a custom TryParse enum to handle claim deserialization:
enum TryParse<T> {
Parsed(T),
FailedToParse, // Set when deserialization fails (e.g. type mismatch)
NotPresent,
}
If a user sends {“nbf”: “99999999999”} (legacy/string format), serde fails to parse it as u64, and it results in TryParse::FailedToParse.
- The Validation Logic Flaw (src/validation.rs): In Validation::validate, the code checks for exp and nbf like this:
// L288-291
if matches!(claims.nbf, TryParse::Parsed(nbf) if options.validate_nbf && nbf > now + options.leeway) {
return Err(new_error(ErrorKind::ImmatureSignature));
}
This matches! macro explicitly looks for TryParse::Parsed(nbf).
• If claims.nbf is FailedToParse, the match returns false. • The if block is skipped. • No error is returned.
- The “Required Claims” Gap: The only fallback mechanism is the “Required Claims” check:
// Lines 259-267
for required_claim in &options.required_spec_claims {
let present = match required_claim.as_str() {
"nbf" => matches!(claims.nbf, TryParse::Parsed(_)),
// ...
};
if !present { return Err(...); }
}
If “nbf” IS in required_spec_claims, FailedToParse will fail the matches!(..., Parsed(_)) check, causing the present to be false, and correctly returning an error.
However, widely accepted usage patterns often enable validation flags (validate_nbf = true) without adding the claim to the required list, assuming that enabling validation implicitly requires the claim’s validity if it appears in the token. jsonwebtoken seems to violate this assumption.
Environment:
• Version: jsonwebtoken 10.2.0 • Rust Version: rustc 1.90.0 • Cargo Version: cargo 1.90.0 • OS: MacOS Tahoe 26.2
POC:
For demonstrating, Here is this simple rust code that demonstrates the bypass. It attempts to validate a token with a string nbf claiming to be valid only in the far future.
create a new project:
cargo new nbf_poc; cd nbf_poc
add required dependencies:
cargo add serde --features derive
cargo add jsonwebtoken --features rust_crypto
cargo add serde_json
replace the code in src/main.rs with this:
use jsonwebtoken::{decode, Validation, Algorithm, DecodingKey, Header, EncodingKey, encode};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct Claims {
sub: String,
nbf: String, // Attacker sends nbf as a String
exp: usize,
}
fn main() {
let key: &[u8; 24] = b"RedMouseOverTheSkyIsBlue";
// nbf is a String "99999999999" (Far future)
// Real nbf should be a Number.
let my_claims: Claims = Claims {
sub: "krishna".to_string(),
nbf: "99999999999".to_string(),
exp: 10000000000,
};
let token: String = encode(&Header::default(), &my_claims, &EncodingKey::from_secret(key)).unwrap();…
- Record
GHSA-h395-gr6q-cpjc- CVSS 4.0
- 5.5 Medium
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:P - Weakness
- CWE-843
- Updated
- 2026-11-02
NVD 5.5
jsonwebtoken is a JWT lib in rust. Prior to version 10.3.0, there is a Type Confusion vulnerability in jsonwebtoken, specifically, in its claim validation logic. When a standard claim (such as nbf or exp) is provided with an incorrect JSON type (Like a String instead of a Number), the library’s internal parsing mechanism marks the claim as “FailedToParse”. Crucially, the validation logic treats this “FailedToParse” state identically to “NotPresent”. This means that if a check is enabled (like: validate_nbf = true), but the claim is not explicitly marked as required in required_spec_claims, the library will skip the validation check entirely for the malformed claim, treating it as if it were not there. This allows attackers to bypass critical time-based security restrictions (like “Not Before” checks) and commit potential authentication and authorization bypasses. This issue has been patched in version 10.3.0.
- Record
CVE-2026-25537- CVSS 4.0
- 5.5 Medium
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:P/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X - CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N - Weakness
- CWE-843
- Updated
- 2026-11-02
OSV 5.5
jsonwebtoken has Type Confusion that leads to potential authorization bypass
jsonwebtoken is a JWT lib in rust. Prior to version 10.3.0, there is a Type Confusion vulnerability in jsonwebtoken, specifically, in its claim validation logic. When a standard claim (such as nbf or exp) is provided with an incorrect JSON type (Like a String instead of a Number), the library’s internal parsing mechanism marks the claim as “FailedToParse”. Crucially, the validation logic treats this “FailedToParse” state identically to “NotPresent”. This means that if a check is enabled (like: validate_nbf = true), but the claim is not explicitly marked as required in required_spec_claims, the library will skip the validation check entirely for the malformed claim, treating it as if it were not there. This allows attackers to bypass critical time-based security restrictions (like “Not Before” checks) and commit potential authentication and authorization bypasses. This issue has been patched in version 10.3.0.
- Record
CVE-2026-25537- CVSS 4.0
- 5.5 Medium
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:P - Weakness
- CWE-843
- Updated
- 2026-11-02
OSVDEBIAN-CVE-2026-25537 7.5
jsonwebtoken is a JWT lib in rust. Prior to version 10.3.0, there is a Type Confusion vulnerability in jsonwebtoken, specifically, in its claim validation logic. When a standard claim (such as nbf or exp) is provided with an incorrect JSON type (Like a String instead of a Number), the library’s internal parsing mechanism marks the claim as “FailedToParse”. Crucially, the validation logic treats this “FailedToParse” state identically to “NotPresent”. This means that if a check is enabled (like: validate_nbf = true), but the claim is not explicitly marked as required in required_spec_claims, the library will skip the validation check entirely for the malformed claim, treating it as if it were not there. This allows attackers to bypass critical time-based security restrictions (like “Not Before” checks) and commit potential authentication and authorization bypasses. This issue has been patched in version 10.3.0.
- Record
DEBIAN-CVE-2026-25537- CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N - Updated
- 2026-11-02
OSVGHSA-h395-gr6q-cpjc 5.5
jsonwebtoken has Type Confusion that leads to potential authorization bypass
Summary:
It has been discovered that there is a Type Confusion vulnerability in jsonwebtoken, specifically, in its claim validation logic.
When a standard claim (such as nbf or exp) is provided with an incorrect JSON type (Like a String instead of a Number), the library’s internal parsing mechanism marks the claim as “FailedToParse”. Crucially, the validation logic treats this “FailedToParse” state identically to “NotPresent”.
This means that if a check is enabled (like: validate_nbf = true), but the claim is not explicitly marked as required in required_spec_claims, the library will skip the validation check entirely for the malformed claim, treating it as if it were not there. This allows attackers to bypass critical time-based security restrictions (like “Not Before” checks) and commit potential authentication and authorization bypasses.
Details:
The vulnerability stems from the interaction between the TryParse enum and the validate function in src/validation.rs.
- The TryParse Enum: The library uses a custom TryParse enum to handle claim deserialization:
enum TryParse<T> {
Parsed(T),
FailedToParse, // Set when deserialization fails (e.g. type mismatch)
NotPresent,
}
If a user sends {“nbf”: “99999999999”} (legacy/string format), serde fails to parse it as u64, and it results in TryParse::FailedToParse.
- The Validation Logic Flaw (src/validation.rs): In Validation::validate, the code checks for exp and nbf like this:
// L288-291
if matches!(claims.nbf, TryParse::Parsed(nbf) if options.validate_nbf && nbf > now + options.leeway) {
return Err(new_error(ErrorKind::ImmatureSignature));
}
This matches! macro explicitly looks for TryParse::Parsed(nbf).
• If claims.nbf is FailedToParse, the match returns false. • The if block is skipped. • No error is returned.
- The “Required Claims” Gap: The only fallback mechanism is the “Required Claims” check:
// Lines 259-267
for required_claim in &options.required_spec_claims {
let present = match required_claim.as_str() {
"nbf" => matches!(claims.nbf, TryParse::Parsed(_)),
// ...
};
if !present { return Err(...); }
}
If “nbf” IS in required_spec_claims, FailedToParse will fail the matches!(..., Parsed(_)) check, causing the present to be false, and correctly returning an error.
However, widely accepted usage patterns often enable validation flags (validate_nbf = true) without adding the claim to the required list, assuming that enabling validation implicitly requires the claim’s validity if it appears in the token. jsonwebtoken seems to violate this assumption.
Environment:
• Version: jsonwebtoken 10.2.0 • Rust Version: rustc 1.90.0 • Cargo Version: cargo 1.90.0 • OS: MacOS Tahoe 26.2
POC:
For demonstrating, Here is this simple rust code that demonstrates the bypass. It attempts to validate a token with a string nbf claiming to be valid only in the far future.
create a new project:
cargo new nbf_poc; cd nbf_poc
add required dependencies:
cargo add serde --features derive
cargo add jsonwebtoken --features rust_crypto
cargo add serde_json
replace the code in src/main.rs with this:
use jsonwebtoken::{decode, Validation, Algorithm, DecodingKey, Header, EncodingKey, encode};
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
struct Claims {
sub: String,
nbf: String, // Attacker sends nbf as a String
exp: usize,
}
fn main() {
let key: &[u8; 24] = b"RedMouseOverTheSkyIsBlue";
// nbf is a String "99999999999" (Far future)
// Real nbf should be a Number.
let my_claims: Claims = Claims {
sub: "krishna".to_string(),
nbf: "99999999999".to_string(),
exp: 10000000000,
};
let token: String = encode(&Header::default(), &my_claims, &EncodingKey::from_secret(key)).unwrap();…
- Record
GHSA-h395-gr6q-cpjc- CVSS 4.0
- 5.5 Medium
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:P - Weakness
- CWE-843
- Updated
- 2026-11-02
OSVUBUNTU-CVE-2026-25537 5.5
jsonwebtoken is a JWT lib in rust. Prior to version 10.3.0, there is a Type Confusion vulnerability in jsonwebtoken, specifically, in its claim validation logic. When a standard claim (such as nbf or exp) is provided with an incorrect JSON type (Like a String instead of a Number), the library’s internal parsing mechanism marks the claim as “FailedToParse”. Crucially, the validation logic treats this “FailedToParse” state identically to “NotPresent”. This means that if a check is enabled (like: validate_nbf = true), but the claim is not explicitly marked as required in required_spec_claims, the library will skip the validation check entirely for the malformed claim, treating it as if it were not there. This allows attackers to bypass critical time-based security restrictions (like “Not Before” checks) and commit potential authentication and authorization bypasses. This issue has been patched in version 10.3.0.
- Record
UBUNTU-CVE-2026-25537- CVSS 4.0
- 5.5 Medium
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N/E:P - CVSS 3.1
- 7.5 High
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:H/A:N - Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
jsonwebtokencrates.io | before 10.3.0 | 10.3.0 |
rust-jsonwebtokenDebian:12 | All versions, plus listed versions 8.2.0-18.3.0-18.3.0-28.3.0-38.3.0-48.3.0-59.3.1-1 | None known |
rust-jsonwebtokenDebian:13 | All versions, plus listed versions 8.3.0-59.3.1-1 | None known |
rust-jsonwebtokenDebian:14 | All versions, plus listed versions 8.3.0-59.3.1-1 | None known |
rust-jsonwebtokenUbuntu:24.04:LTS | All versions, plus listed versions 8.3.0-18.3.0-3 | None known |
rust-jsonwebtokenUbuntu:25.10 | All versions, plus listed versions 8.3.0-5 | None known |
rust-jsonwebtokenUbuntu:26.10 | All versions, plus listed versions 9.3.1-1 | None known |
rust-jsonwebtokenUbuntu:26.04:LTS | All versions, plus listed versions 8.3.0-59.3.1-1 | None known |
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-25537 is a medium vulnerability (CVSS 5.5) in Keats Jsonwebtoken, published February 3, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.50%, the 43rd percentile. Fixed in jsonwebtoken 10.3.0.
References
github.com/Keats/jsonwebtoken/security/advisories/GHSA-h395-gr6q-cpjc
github.com/Keats/jsonwebtoken/commit/abbc3076742c4161347bc6b8bf4aa5eb86e1dc01
nvd.nist.gov/vuln/detail/CVE-2026-25537
github.com/advisories/GHSA-h395-gr6q-cpjc
github.com/CVEProject/cvelistV5/tree/main/cves/2026/25xxx/CVE-2026-25537.json
security-tracker.debian.org/tracker/CVE-2026-25537
github.com/Keats/jsonwebtoken
ubuntu.com/security/CVE-2026-25537
cve.org/CVERecord?id=CVE-2026-25537
Left out here: the rest of 2 source descriptions. The JSON record has them.