Detect JHipster Generator Vulnerability CVE-2019-16303¶
ID: java/jhipster-prng
Kind: problem
Security severity: 7.8
Severity: error
Precision: very-high
Tags:
- security
- external/cwe/cwe-338
Query suites:
- java-code-scanning.qls
- java-security-extended.qls
- java-security-and-quality.qls
Click to see the query in the CodeQL repository
This query detects instances of RandomUtil.java that were generated by a JHipster version that is vulnerable to CVE-2019-16303.
If an app uses RandomUtil.java generated by a vulnerable version of JHipster, attackers can request a password reset token and use this to predict the value of future reset tokens generated by this server. Using this information, they can create a reset link that allows them to take over any account.
This vulnerability has a CVSS v3.0 Base Score of 9.8/10 .
Example¶
The example below shows the vulnerable RandomUtil class generated by JHipster prior to version 6.3.0.
import org.apache.commons.lang3.RandomStringUtils;
/**
* Utility class for generating random Strings.
*/
public final class RandomUtil {
private static final int DEF_COUNT = 20;
private RandomUtil() {
}
/**
* Generate a password.
*
* @return the generated password.
*/
public static String generatePassword() {
return RandomStringUtils.randomAlphanumeric(DEF_COUNT); // BAD: RandomStringUtils does not use SecureRandom
}
/**
* Generate an activation key.
*
* @return the generated activation key.
*/
public static String generateActivationKey() {
return RandomStringUtils.randomNumeric(DEF_COUNT); // BAD: RandomStringUtils does not use SecureRandom
}
/**
* Generate a reset key.
*
* @return the generated reset key.
*/
public static String generateResetKey() {
return RandomStringUtils.randomNumeric(DEF_COUNT); // BAD: RandomStringUtils does not use SecureRandom
}
/**
* Generate a unique series to validate a persistent token, used in the
* authentication remember-me mechanism.
*
* @return the generated series data.
*/
public static String generateSeriesData() {
return RandomStringUtils.randomAlphanumeric(DEF_COUNT); // BAD: RandomStringUtils does not use SecureRandom
}
/**
* Generate a persistent token, used in the authentication remember-me mechanism.
*
* @return the generated token data.
*/
public static String generateTokenData() {
return RandomStringUtils.randomAlphanumeric(DEF_COUNT); // BAD: RandomStringUtils does not use SecureRandom
}
}
Below is a fixed version of the RandomUtil class.
import org.apache.commons.lang3.RandomStringUtils;
import java.security.SecureRandom;
/**
* Utility class for generating random Strings.
*/
public final class RandomUtil {
private static final SecureRandom SECURE_RANDOM = new SecureRandom(); // GOOD: Using SecureRandom
private static final int DEF_COUNT = 20;
static {
SECURE_RANDOM.nextBytes(new byte[64]);
}
private RandomUtil() {
}
private static String generateRandomAlphanumericString() {
// GOOD: Passing Secure Random to RandomStringUtils::random
return RandomStringUtils.random(DEF_COUNT, 0, 0, true, true, null, SECURE_RANDOM);
}
/**
* Generate a password.
*
* @return the generated password.
*/
public static String generatePassword() {
return generateRandomAlphanumericString();
}
/**
* Generate an activation key.
*
* @return the generated activation key.
*/
public static String generateActivationKey() {
return generateRandomAlphanumericString();
}
/**
* Generate a reset key.
*
* @return the generated reset key.
*/
public static String generateResetKey() {
return generateRandomAlphanumericString();
}
/**
* Generate a unique series to validate a persistent token, used in the
* authentication remember-me mechanism.
*
* @return the generated series data.
*/
public static String generateSeriesData() {
return generateRandomAlphanumericString();
}
/**
* Generate a persistent token, used in the authentication remember-me mechanism.
*
* @return the generated token data.
*/
public static String generateTokenData() {
return generateRandomAlphanumericString();
}
}
Recommendation¶
You should refactor the RandomUtil class and replace every call to RandomStringUtils.randomAlphaNumeric. You could regenerate the class using the latest version of JHipster, or use an automated refactoring. For example, using the Patching JHipster CWE-338 for the Rewrite project.
References¶
Cloudflare Blog: Why secure systems require random numbers
Hacker News: How I Hacked Hacker News (with arc security advisory)
Posts by Pucara Information Security Team: The Java Soothsayer: A practical application for insecure randomness. (Includes free 0day)
Common Weakness Enumeration: CWE-338.