CVE-2019-16303 (Other, published 2019-09-14T00:15Z)
Description: value: A class generated by the Generator in JHipster before 6.3.0 and JHipster Kotlin through 1.1.0 produces code that uses an insecure source of randomness (apache.commons.lang3 RandomStringUtils). This allows an attacker (if able to obtain their own password reset URL) to compute the value for all other password resets for other accounts, thus allowing privilege escalation or account takeover.
Severity: HIGH (CVSS v3 base score: 9.8)
Weakness: CWE-338 \u2014 Use of Cryptographically Weak Pseudo-Random Number Generator (PRNG)
The product uses a Pseudo-Random Number Generator (PRNG) in a security context, but the PRNG's algorithm is not cryptographically strong.
Repository: https://github.com/jhipster/generator-jhipster
Files changed:
generators/server/templates/src/main/java/package/security/PersistentTokenRememberMeServices.java.ejs
generators/server/templates/src/main/java/package/service/UserService.java.ejs
generators/server/templates/src/main/java/package/service/util/RandomUtil.java.ejs
generators/server/templates/src/test/java/package/service/UserServiceIT.java.ejs
Commit message: use new SecureRandom which uses non blocking /dev/urandom


Vulnerable code:
                token.setTokenValue(RandomUtil.getInstance().generateTokenData());
            t.setSeries(RandomUtil.getInstance().generateSeriesData());<% if (databaseType === 'sql' || databaseType === 'mongodb') { %>
            t.setTokenValue(RandomUtil.getInstance().generateTokenData());
                user.setResetKey(RandomUtil.getInstance().generateResetKey());
        newUser.setActivationKey(RandomUtil.getInstance().generateActivationKey());
                newUser.setActivationKey(RandomUtil.getInstance().generateActivationKey());
        String encryptedPassword = passwordEncoder.encode(RandomUtil.getInstance().generatePassword());
        user.setResetKey(RandomUtil.getInstance().generateResetKey());
    private static final RandomUtil INSTANCE = new RandomUtil();

    public static RandomUtil getInstance() {
        return INSTANCE;
    }

    private final SecureRandom secureRandom;
        try {
            secureRandom = SecureRandom.getInstanceStrong();
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException("Unable to find secure algorithms.", e); //NOSONAR
        }
    private String generateRandomAlphanumericString() {
    public String generatePassword() {
    public String generateActivationKey() {
    public String generateResetKey() {
    public String generateSeriesData() {
    public String generateTokenData() {
        String resetKey = RandomUtil.getInstance().generateResetKey();
        String resetKey = RandomUtil.getInstance().generateResetKey();

Fixed code:
                token.setTokenValue(RandomUtil.generateTokenData());
            t.setSeries(RandomUtil.generateSeriesData());<% if (databaseType === 'sql' || databaseType === 'mongodb') { %>
            t.setTokenValue(RandomUtil.generateTokenData());
                user.setResetKey(RandomUtil.generateResetKey());
        newUser.setActivationKey(RandomUtil.generateActivationKey());
                newUser.setActivationKey(RandomUtil.generateActivationKey());
        String encryptedPassword = passwordEncoder.encode(RandomUtil.generatePassword());
        user.setResetKey(RandomUtil.generateResetKey());
    private static final SecureRandom secureRandom = new SecureRandom(new SecureRandom().generateSeed(128));
    private static String generateRandomAlphanumericString() {
    public static String generatePassword() {
    public static String generateActivationKey() {
    public static String generateResetKey() {
    public static String generateSeriesData() {
    public static String generateTokenData() {
        String resetKey = RandomUtil.generateResetKey();
        String resetKey = RandomUtil.generateResetKey();