VYPR
Moderate severityNVD Advisory· Published Jul 11, 2014· Updated May 6, 2026

CVE-2014-3503

CVE-2014-3503

Description

Apache Syncope 1.1.x before 1.1.8 uses weak random values to generate passwords, which makes it easier for remote attackers to guess the password via a brute force attack.

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
org.apache.syncope:syncopeMaven
>= 1.1.0, < 1.1.81.1.8

Affected products

8
  • Apache/Syncope8 versions
    cpe:2.3:a:apache:syncope:1.1.0:*:*:*:*:*:*:*+ 7 more
    • cpe:2.3:a:apache:syncope:1.1.0:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:syncope:1.1.1:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:syncope:1.1.2:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:syncope:1.1.3:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:syncope:1.1.4:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:syncope:1.1.5:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:syncope:1.1.6:*:*:*:*:*:*:*
    • cpe:2.3:a:apache:syncope:1.1.7:*:*:*:*:*:*:*

Patches

1
8e0045925a38

Better password generation

https://github.com/apache/syncopeColm O HeigeartaighMay 21, 2014via ghsa
2 files changed · +37 33
  • core/src/main/java/org/apache/syncope/core/connid/PasswordGenerator.java+20 23 modified
    @@ -20,7 +20,7 @@
     
     import java.util.ArrayList;
     import java.util.List;
    -import org.apache.commons.lang3.RandomStringUtils;
    +
     import org.apache.commons.lang3.StringUtils;
     import org.apache.syncope.common.types.PasswordPolicySpec;
     import org.apache.syncope.core.persistence.beans.ExternalResource;
    @@ -30,6 +30,7 @@
     import org.apache.syncope.core.persistence.dao.PolicyDAO;
     import org.apache.syncope.core.policy.PolicyPattern;
     import org.apache.syncope.core.util.InvalidPasswordPolicySpecException;
    +import org.apache.syncope.core.util.SecureRandomUtil;
     import org.springframework.beans.factory.annotation.Autowired;
     import org.springframework.stereotype.Component;
     
    @@ -41,7 +42,7 @@
     @Component
     public class PasswordGenerator {
     
    -    private static final String[] SPECIAL_CHARS = {"", "!", "£", "%", "&", "(", ")", "?", "#", "_", "$"};
    +    private static final char[] SPECIAL_CHARS = {'!', '£', '%', '&', '(', ')', '?', '#', '$'};
     
         @Autowired
         private PolicyDAO policyDAO;
    @@ -216,56 +217,51 @@ private String generate(final PasswordPolicySpec policySpec) {
             //filled empty chars
             for (int firstEmptyChar = firstEmptyChar(generatedPassword);
                     firstEmptyChar < generatedPassword.length - 1; firstEmptyChar++) {
    -            generatedPassword[firstEmptyChar] = RandomStringUtils.randomAlphabetic(1);
    +            generatedPassword[firstEmptyChar] = SecureRandomUtil.generateRandomLetter();
             }
     
             checkPrefixAndSuffix(generatedPassword, policySpec);
     
             return StringUtils.join(generatedPassword);
         }
     
    -    private int randomNumber(final int range) {
    -        int randomNumber = (int) (Math.random() * (range - 1));
    -        return randomNumber == 0 ? 1 : randomNumber;
    -    }
    -
         private void checkStartChar(final String[] generatedPassword, final PasswordPolicySpec policySpec) {
             if (policySpec.isMustStartWithAlpha()) {
    -            generatedPassword[0] = RandomStringUtils.randomAlphabetic(1);
    +            generatedPassword[0] = SecureRandomUtil.generateRandomLetter();
             }
             if (policySpec.isMustStartWithNonAlpha() || policySpec.isMustStartWithDigit()) {
    -            generatedPassword[0] = RandomStringUtils.randomNumeric(1);
    +            generatedPassword[0] = SecureRandomUtil.generateRandomNumber();
             }
             if (policySpec.isMustntStartWithAlpha()) {
    -            generatedPassword[0] = RandomStringUtils.randomNumeric(1);
    +            generatedPassword[0] = SecureRandomUtil.generateRandomNumber();
     
             }
             if (policySpec.isMustntStartWithDigit()) {
    -            generatedPassword[0] = RandomStringUtils.randomAlphabetic(1);
    +            generatedPassword[0] = SecureRandomUtil.generateRandomLetter();
     
             }
             if (policySpec.isMustntStartWithNonAlpha()) {
    -            generatedPassword[0] = RandomStringUtils.randomAlphabetic(1);
    +            generatedPassword[0] = SecureRandomUtil.generateRandomLetter();
     
             }
         }
     
         private void checkEndChar(final String[] generatedPassword, final PasswordPolicySpec policySpec) {
             if (policySpec.isMustEndWithAlpha()) {
    -            generatedPassword[policySpec.getMinLength() - 1] = RandomStringUtils.randomAlphabetic(1);
    +            generatedPassword[policySpec.getMinLength() - 1] = SecureRandomUtil.generateRandomLetter();
             }
             if (policySpec.isMustEndWithNonAlpha() || policySpec.isMustEndWithDigit()) {
    -            generatedPassword[policySpec.getMinLength() - 1] = RandomStringUtils.randomNumeric(1);
    +            generatedPassword[policySpec.getMinLength() - 1] = SecureRandomUtil.generateRandomNumber();
             }
     
             if (policySpec.isMustntEndWithAlpha()) {
    -            generatedPassword[policySpec.getMinLength() - 1] = RandomStringUtils.randomNumeric(1);
    +            generatedPassword[policySpec.getMinLength() - 1] = SecureRandomUtil.generateRandomNumber();
             }
             if (policySpec.isMustntEndWithDigit()) {
    -            generatedPassword[policySpec.getMinLength() - 1] = RandomStringUtils.randomAlphabetic(1);
    +            generatedPassword[policySpec.getMinLength() - 1] = SecureRandomUtil.generateRandomLetter();
             }
             if (policySpec.isMustntEndWithNonAlpha()) {
    -            generatedPassword[policySpec.getMinLength() - 1] = RandomStringUtils.randomAlphabetic(1);
    +            generatedPassword[policySpec.getMinLength() - 1] = SecureRandomUtil.generateRandomLetter();
     
             }
         }
    @@ -282,26 +278,26 @@ private void checkRequired(final String[] generatedPassword, final PasswordPolic
             if (policySpec.isDigitRequired()
                     && !PolicyPattern.DIGIT.matcher(StringUtils.join(generatedPassword)).matches()) {
     
    -            generatedPassword[firstEmptyChar(generatedPassword)] = RandomStringUtils.randomNumeric(1);
    +            generatedPassword[firstEmptyChar(generatedPassword)] = SecureRandomUtil.generateRandomNumber();
             }
     
             if (policySpec.isUppercaseRequired()
                     && !PolicyPattern.ALPHA_UPPERCASE.matcher(StringUtils.join(generatedPassword)).matches()) {
     
    -            generatedPassword[firstEmptyChar(generatedPassword)] = RandomStringUtils.randomAlphabetic(1).toUpperCase();
    +            generatedPassword[firstEmptyChar(generatedPassword)] = SecureRandomUtil.generateRandomLetter().toUpperCase();
             }
     
             if (policySpec.isLowercaseRequired()
                     && !PolicyPattern.ALPHA_LOWERCASE.matcher(StringUtils.join(generatedPassword)).matches()) {
     
    -            generatedPassword[firstEmptyChar(generatedPassword)] = RandomStringUtils.randomAlphabetic(1).toLowerCase();
    +            generatedPassword[firstEmptyChar(generatedPassword)] = SecureRandomUtil.generateRandomLetter().toLowerCase();
             }
     
             if (policySpec.isNonAlphanumericRequired()
                     && !PolicyPattern.NON_ALPHANUMERIC.matcher(StringUtils.join(generatedPassword)).matches()) {
     
    -            generatedPassword[firstEmptyChar(generatedPassword)] =
    -                    SPECIAL_CHARS[randomNumber(SPECIAL_CHARS.length - 1)];
    +            generatedPassword[firstEmptyChar(generatedPassword)] = 
    +                SecureRandomUtil.generateRandomSpecialCharacter(SPECIAL_CHARS);
             }
         }
     
    @@ -318,4 +314,5 @@ private void checkPrefixAndSuffix(final String[] generatedPassword, final Passwo
                 }
             }
         }
    +    
     }
    
  • core/src/main/java/org/apache/syncope/core/util/SecureRandomUtil.java+17 10 modified
    @@ -19,19 +19,26 @@
     package org.apache.syncope.core.util;
     
     import java.security.SecureRandom;
    -import java.util.Random;
    +
    +import org.apache.commons.lang3.RandomStringUtils;
     
     public class SecureRandomUtil {
    +    
    +    private static final SecureRandom RANDOM = new SecureRandom();
     
         public static String generateRandomPassword(final int tokenLength) {
    -        Random random = new SecureRandom();
    -
    -        final String letters = "abcdefghjkmnpqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ0123456789";
    -
    -        String pw = "";
    -        for (int i = 0; i < tokenLength; i++) {
    -            pw += letters.charAt((int) (random.nextDouble() * letters.length()));
    -        }
    -        return pw;
    +        return RandomStringUtils.random(tokenLength, 0, 0, true, false, null, RANDOM);
    +    }
    +    
    +    public static String generateRandomLetter() {
    +        return RandomStringUtils.random(1, 0, 0, true, false, null, RANDOM);
    +    }
    +    
    +    public static String generateRandomNumber() {
    +        return RandomStringUtils.random(1, 0, 0, false, true, null, RANDOM);
    +    }
    +    
    +    public static String generateRandomSpecialCharacter(char[] characters) {
    +        return RandomStringUtils.random(1, 0, 0, false, false, characters, RANDOM);
         }
     }
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

11

News mentions

0

No linked articles in our index yet.