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.
| Package | Affected versions | Patched versions |
|---|---|---|
org.apache.syncope:syncopeMaven | >= 1.1.0, < 1.1.8 | 1.1.8 |
Affected products
8cpe: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
18e0045925a38Better password generation
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- syncope.apache.org/security.htmlnvdVendor Advisory
- github.com/advisories/GHSA-4c72-mrhf-23cgghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2014-3503ghsaADVISORY
- packetstormsecurity.com/files/127375/Apache-Syncope-Insecure-Password-Generation.htmlnvdWEB
- svn.apache.org/viewvcghsaWEB
- github.com/apache/syncope/commit/8e0045925a387ee211832c7e0709dd418cda1ad3ghsaWEB
- syncope.apache.org/security.htmlghsaWEB
- web.archive.org/web/20140728093808/http://www.securityfocus.com/bid/68431ghsaWEB
- web.archive.org/web/20201207014021/http://www.securityfocus.com/archive/1/532669/100/0/threadedghsaWEB
- www.securityfocus.com/archive/1/532669/100/0/threadednvd
- www.securityfocus.com/bid/68431nvd
News mentions
0No linked articles in our index yet.