Skip to content

Invalid generation password rules in retry case #158

@Alexgon10

Description

@Alexgon10

I have the following case: the password should contain at least 3 lowercase letters, 3 uppercase letters, 3 digits, and should not repeat the same character more than 3 times.

The PasswordGeneration process includes a retry mechanism to regenerate the password if any non-character rules are invalid.
However, we encounter a problem in this case.

 public String generatePassword(final int length, final List<? extends Rule> rules)
  {
    if (length <= 0) {
      throw new IllegalArgumentException("length must be greater than 0");
    }

    final StringBuilder allChars = new StringBuilder();
    final CharBuffer buffer = CharBuffer.allocate(length);
    final PasswordValidator validator = new PasswordValidator(rules);
    if (rules != null) {
      for (Rule rule : rules) {
        if (rule instanceof CharacterRule) {
          final CharacterRule characterRule = (CharacterRule) rule;
          fillRandomCharacters(
                  characterRule.getValidCharacters(),
                  Math.min(length, characterRule.getNumberOfCharacters()),
                  buffer);
          allChars.append(characterRule.getValidCharacters());
        }
      }
    }
    String generated;
    int count = 0;
    do {
      fillRandomCharacters(allChars, length - buffer.position(), buffer);
      // cast to Buffer prevents NoSuchMethodError when compiled on JDK9+ and run on JDK8
      ((Buffer) buffer).flip();
      randomize(buffer);
      generated = buffer.toString();
      if (count > 0) {
        retryCount++;
      }
    } while (count++ <= RETRY_LIMIT && !validator.validate(new PasswordData(generated)).isValid());
    if (count > RETRY_LIMIT) {
      throw new IllegalStateException("Exceeded maximum number of password generation retries");
    }
    return generated;
  }

If any of the non-character rules are invalid, the second while loop starts without going through the character rules loop, and the password is generated using only the available allChars. This process ignores the rules regarding the required number of characters.
The regenerated password from the second loop also becomes invalid due to the required number of character rule.
As a result, after 2 retries a generation error occurs.
It seems that during the password regeneration, all the characters rules should be considered as well.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions