GHSA-29wx-vh33-7x7r CVE-2024-51744 GO-2024-3250
Bad documentation of error handling in ParseWithClaims can lead to potentially dangerous situations
- Severity
- 0.0 / 10
- Low · CVSS 4.0
- Exploit chance (EPSS)
- 0.58%
- Chance of exploitation in the next 30 days. Higher than 47.96% of scored vulnerabilities.
- Known exploited
- No
- Not in CISA's catalog
- Weakness
- CWE-347 Improper Verification of Cryptographic Signature
- CWE-755 Improper Handling of Exceptional Conditions
- Fix
4.5.1- Upgrade github.com/golang-jwt/jwt/v4 to this version or later
Description
Summary
Unclear documentation of the error behavior in ParseWithClaims can lead to situation where users are potentially not checking errors in the way they should be. Especially, if a token is both expired and invalid, the errors returned by ParseWithClaims return both error codes. If users only check for the jwt.ErrTokenExpired using error.Is, they will ignore the embedded jwt.ErrTokenSignatureInvalid and thus potentially accept invalid tokens.
Fix
We have back-ported the error handling logic from the v5 branch to the v4 branch. In this logic, the ParseWithClaims function will immediately return in "dangerous" situations (e.g., an invalid signature), limiting the combined errors only to situations where the signature is valid, but further validation failed (e.g., if the signature is valid, but is expired AND has the wrong audience). This fix is part of the 4.5.1 release.
Workaround
We are aware that this changes the behaviour of an established function and is not 100 % backwards compatible, so updating to 4.5.1 might break your code. In case you cannot update to 4.5.0, please make sure that you are properly checking for all errors ("dangerous" ones first), so that you are not running in the case detailed above.
token, err := /* jwt.Parse or similar */
if token.Valid {
fmt.Println("You look nice today")
} else if errors.Is(err, jwt.ErrTokenMalformed) {
fmt.Println("That's not even a token")
} else if errors.Is(err, jwt.ErrTokenUnverifiable) {
fmt.Println("We could not verify this token")
} else if errors.Is(err, jwt.ErrTokenSignatureInvalid) {
fmt.Println("This token has an invalid signature")
} else if errors.Is(err, jwt.ErrTokenExpired) || errors.Is(err, jwt.ErrTokenNotValidYet) {
// Token is either expired or not active yet
fmt.Println("Timing is everything")
} else {
fmt.Println("Couldn't handle this token:", err)
}
Affected versions
Go
| Package | Vulnerable | Fixed in |
|---|---|---|
| github.com/golang-jwt/jwt/v4 | < 4.5.1 |
4.5.1 |
How to fix
Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.
github.com/golang-jwt/jwt/v4 Go → 4.5.1
- go
go get github.com/golang-jwt/jwt/v4@v4.5.1 && go mod tidy
Severity breakdown
CVSS 4.0 0.0
CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:P/VC:L/VI:N/VA:N/SC:N/SI:N/SA:N
- Attack vector
- Network
- Attack complexity
- Low
- Attack requirements
- Present
- Privileges required
- None
- User interaction
- Passive
- Confidentiality (vulnerable system)
- Low
- Integrity (vulnerable system)
- None
- Availability (vulnerable system)
- None
- Confidentiality (subsequent systems)
- None
- Integrity (subsequent systems)
- None
- Availability (subsequent systems)
- None
CVSS 3.1 3.1
CVSS:3.1/AV:N/AC:H/PR:N/UI:R/S:U/C:L/I:N/A:N
- Attack vector
- Network
- Attack complexity
- High
- Privileges required
- None
- User interaction
- Required
- Scope
- Unchanged
- Confidentiality
- Low
- Integrity
- None
- Availability
- None
Weakness
CWE-347: Improper Verification of Cryptographic Signature
The product does not verify, or incorrectly verifies, the cryptographic signature for data.
CWE-755: Improper Handling of Exceptional Conditions
The product does not handle or incorrectly handles an exceptional condition.
References
Advisories
Packages
Other links
Timeline
- Published
- Last updated by the source
- Latest EPSS score
Related advisories
| Advisory | Severity | Why it's related |
|---|---|---|
| GHSA-mh63-6h87-95cp jwt-go allows excessive memory allocation during header parsing | High | Also affects github.com/golang-jwt/jwt/v4 |
| EEF-CVE-2026-65632 ECDSA signature length is not validated in jose, allowing signature malleability | Not rated yet | Same weakness, CWE-347 |
| GHSA-pxh4-856f-4h89 PyJWT: HS256/384/512 verify accepts empty HMAC key via oct JWK (PyJWK/PyJWKClient) enabling token forgery | High | Same weakness, CWE-347 |
| GHSA-j7h2-66j4-ghjf A russh SSH server accepts a publickey authentication whose signature uses a different algorithm than the one named in the request | Low | Same weakness, CWE-347 |
| GHSA-w2cx-738m-mc7w PyJWT accepts public JWK containers as HMAC secrets | High | Same weakness, CWE-347 |
| GHSA-r6x4-923q-g947 PyJWT BOM Bypass | High | Same weakness, CWE-347 |
| GHSA-p4g4-x82p-q773 PyJWT: Public keys in DER form are accepted as HMAC secrets, bypassing the CVE-2022-29217 guard | High | Same weakness, CWE-347 |
| GHSA-ffc3-869f-jxw9 PyJWT: Asymmetric-PEM detection bypass: whitespace/line-ending-mutated public keys skip the HS/asymmetric confusion guard | Critical | Same weakness, CWE-347 |
MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.
Check your repos with MergeHarbor