Class: DeviseSecurity::PasswordComplexityValidator

Inherits:
ActiveModel::EachValidator
  • Object
show all
Defined in:
lib/devise-security/validators/password_complexity_validator.rb

Overview

(NIST) does not recommend the use of a password complexity checks because…

> Length and complexity requirements beyond those recommended here > significantly increase the difficulty of memorized secrets and increase user > frustration. As a result, users often work around these restrictions in a > way that is counterproductive. Furthermore, other mitigations such as > blacklists, secure hashed storage, and rate limiting are more effective at > preventing modern brute-force attacks. Therefore, no additional complexity > requirements are imposed.

Options:

  • ‘digit | digits`: minimum number of digits in the validated string. Uses the `digit` localization key.

  • ‘lower`: minimum number of lower-case letters in the validated string

  • ‘symbol | symbols`: minimum number of punctuation characters or symbols in the validated string. Uses the `symbol` localization key.

  • ‘upper`: minimum number of upper-case letters in the validated string

Instance Method Summary collapse

Instance Method Details

#patternsHash<Symbol,Regexp>

A Hash of the possible valid patterns that can be checked against. The keys for this Hash are singular symbols corresponding to entries in the localization files. Override or redefine this method if you want to include custom patterns (e.g., ‘letter: /pAlpha/` for all letters).

Returns:

  • (Hash<Symbol,Regexp>)


28
29
30
31
32
33
34
35
# File 'lib/devise-security/validators/password_complexity_validator.rb', line 28

def patterns
  {
    digit: /\p{Digit}/,
    lower: /\p{Lower}/,
    symbol: /\p{Punct}|\p{S}/,
    upper: /\p{Upper}/
  }
end

#validate_each(record, attribute, password) ⇒ Object

Validate the complexity of the password. This validation does not check to ensure the password is not blank. That is the responsibility of other validations. This validator will also ignore any patterns that are not explicitly configured to be used or whose minimum limits are less than 1.

Parameters:

  • record (ActiveModel::Model)
  • attribute (Symbol)
  • password (String)


45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/devise-security/validators/password_complexity_validator.rb', line 45

def validate_each(record, attribute, password)
  return if password.blank?

  options.sort.each do |pattern_name, minimum|
    normalized_option = pattern_name.to_s.singularize.to_sym

    next unless patterns.key?(normalized_option)
    next unless minimum.positive?
    next if password.scan(patterns[normalized_option]).size >= minimum

    record.errors.add(
      attribute,
      :"password_complexity.#{normalized_option}",
      count: minimum
    )
  end
end