title: Password validator against a weak password list that may contain single characters
body: <p><strong>1.</strong> There is a password-validating functionality in our product checking the entered phrase against a weak password list. The following method removes parts of the password that hit against this list:</p>
  
  <pre><code>import org.apache.commons.lang.StringUtils;
  
  private String removeContaining(final String passwd, final List&lt;String&gt; list) {
      String lpasswd = passwd.toLowerCase();
      for (final String element : list) {
          if (element != null) {
              lpasswd = StringUtils.remove(lpasswd, element.toLowerCase());  //removing the hits
          }
      }
      return lpasswd;
  }
  </code></pre>
  
  <p>And then the rest is checked to compile with minimal length and other criteria. 
  What would be the better way to refactor this method if the banned list may contain single characters?</p>
  
  <p>So, for examples, if list contains "a" and "b", the entered password is "abc23b$aa" it will become "c23$". Or we should forbid our customers to put 1-letters words in such lists?  </p>
  
  <p><strong>2.</strong> Having investigating this issue I found a description of Azure-password handling mechanism:
  <a href="https://docs.microsoft.com/en-us/azure/active-directory/authentication/concept-password-ban-bad#step-2-check-if-password-is-considered-banned" rel="nofollow noreferrer">https://docs.microsoft.com/en-us/azure/active-directory/authentication/concept-password-ban-bad#step-2-check-if-password-is-considered-banned</a>
  From the article: </p>
  
  <blockquote>
    <p>Each banned password that is found in a user’s password is given one
    point. Each remaining unique character is given one point. A password
    must be at least five (5) points for it to be accepted. For the next
    two examples, let’s assume that Contoso is using Azure AD Password
    Protection and has “contoso” on their custom list. Let’s also assume
    that “blank” is on the global list.</p>
    
    <p>Example: a user changes their password to “C0ntos0Blank12”</p>
    
    <p>After normalization, this password becomes “contosoblank12”. The
    matching process finds that this password contains two banned
    passwords: contoso and blank. This password is then given a score:</p>
    
    <p>[contoso] + [blank] + <a href="https://docs.microsoft.com/en-us/azure/active-directory/authentication/concept-password-ban-bad#step-2-check-if-password-is-considered-banned" rel="nofollow noreferrer">1</a> + [2] = 4 points Since this password is
    under five (5) points, it will be rejected.</p>
  </blockquote>
  
  <p>But if the dictionary contains "Contoso" and "cont" how the overall scoring would be calculated (matching against "contoso" or against "cont")? </p>
  
  <p>Thanks.</p>