Ensure PAM Enforces Password Requirements - Minimum Digit Characters

Classification:

compliance

Framework:

Control:

Description

The pam_pwquality module’s dcredit parameter controls requirements for usage of digits in a password. When set to a negative number, any password will be required to contain that many digits. When set to a positive number, pam_pwquality will grant +1 additional length credit for each digit. Modify the dcredit setting in /etc/security/pwquality.conf to require the use of a digit in passwords.

Rationale

Use of a complex password helps to increase the time and resources required to compromise the password. Password complexity, or strength, is a measure of the effectiveness of a password in resisting attempts at guessing and brute-force attacks.

Password complexity is one factor of several that determines how long it takes to crack a password. The more complex the password, the greater the number of possible combinations that need to be tested before the password is compromised. Requiring digits makes password guessing attacks more difficult by ensuring a larger search space.

Remediation

Shell script

The following script can be run on the host to remediate the issue.

# Remediation is applicable only in certain platforms
if dpkg-query --show --showformat='${db:Status-Status}\n' 'libpam-runtime' 2>/dev/null | grep -q installed; then

var\_password\_pam\_dcredit='-1'






# Strip any search characters in the key arg so that the key can be replaced without
# adding any search characters to the config file.
stripped\_key=$(sed 's/[\^=\$,;+]\*//g' <<< "^dcredit")

# shellcheck disable=SC2059
printf -v formatted\_output "%s = %s" "$stripped\_key" "$var\_password\_pam\_dcredit"

# If the key exists, change it. Otherwise, add it to the config\_file.
# We search for the key string followed by a word boundary (matched by \>),
# so if we search for 'setting', 'setting2' won't match.
if LC\_ALL=C grep -q -m 1 -i -e "^dcredit\\>" "/etc/security/pwquality.conf"; then
 escaped\_formatted\_output=$(sed -e 's|/|\\/|g' <<< "$formatted\_output")
 LC\_ALL=C sed -i --follow-symlinks "s/^dcredit\\>.\*/$escaped\_formatted\_output/gi" "/etc/security/pwquality.conf"
else
 if [[ -s "/etc/security/pwquality.conf" ]] && [[ -n "$(tail -c 1 -- "/etc/security/pwquality.conf" || true)" ]]; then
 LC\_ALL=C sed -i --follow-symlinks '$a'\\ "/etc/security/pwquality.conf"
 fi
 printf '%s\n' "$formatted\_output" >> "/etc/security/pwquality.conf"
fi

else
 >&2 echo 'Remediation is not applicable, nothing was done'
fi

Ansible playbook

The following playbook can be run with Ansible to remediate the issue.

- name: Gather the package facts
 package\_facts:
 manager: auto
 tags:
 - DISA-STIG-UBTU-20-010052
 - NIST-800-53-CM-6(a)
 - NIST-800-53-IA-5(1)(a)
 - NIST-800-53-IA-5(4)
 - NIST-800-53-IA-5(c)
 - PCI-DSS-Req-8.2.3
 - PCI-DSSv4-8.3.6
 - PCI-DSSv4-8.3.9
 - accounts\_password\_pam\_dcredit
 - low\_complexity
 - low\_disruption
 - medium\_severity
 - no\_reboot\_needed
 - restrict\_strategy
- name: XCCDF Value var\_password\_pam\_dcredit # promote to variable
 set\_fact:
 var\_password\_pam\_dcredit: !!str -1
 tags:
 - always

- name: Ensure PAM Enforces Password Requirements - Minimum Digit Characters - Ensure
 PAM variable dcredit is set accordingly
 ansible.builtin.lineinfile:
 create: true
 dest: /etc/security/pwquality.conf
 regexp: ^#?\s\*dcredit
 line: dcredit = {{ var\_password\_pam\_dcredit }}
 when: '"libpam-runtime" in ansible\_facts.packages'
 tags:
 - DISA-STIG-UBTU-20-010052
 - NIST-800-53-CM-6(a)
 - NIST-800-53-IA-5(1)(a)
 - NIST-800-53-IA-5(4)
 - NIST-800-53-IA-5(c)
 - PCI-DSS-Req-8.2.3
 - PCI-DSSv4-8.3.6
 - PCI-DSSv4-8.3.9
 - accounts\_password\_pam\_dcredit
 - low\_complexity
 - low\_disruption
 - medium\_severity
 - no\_reboot\_needed
 - restrict\_strategy