# yaml-language-server: $schema=../../../../schema/control.schema.json id: CB-DEB-AUTH-012 title: Prevent reuse of recent passwords finding: title: Users can set a password they used before description: Users forced to change a password can switch back to the old one, which may already be known to an attacker. status: active profiles: [core] risk: severity: low assessment: automated tags: [pam, password] description: | `pam_pwhistory` (in `libpam-modules`) keeps the hashes of each user's last passwords in `/etc/security/opasswd` and refuses a new password that matches one of the last `remember`. Debian ships the module but does not enable it; a `pam-auth-update` profile adds it to the password stack, after the quality check and before `pam_unix`. rationale: | When a password is changed after a suspected compromise, going back to the previous one undoes the change. Remembering recent passwords also stops users from cycling between two values. impact: | Users cannot reuse their last {{ remember }} passwords. The history file grows by one hash per user and change. setting: location: /usr/share/pam-configs/cirsec_pwhistory default_value: Not enabled recommended_value: "remember={{ remember }}, enforce_for_root, use_authtok" parameters: - name: remember type: integer description: Number of previous passwords that cannot be reused. default: 24 minimum: 5 maximum: 400 audit: manual: | `/etc/pam.d/common-password` must contain a `pam_pwhistory.so` line with `remember=` of at least {{ remember }}, `enforce_for_root` and `use_authtok`, placed before `pam_unix.so`. checks: - id: module engine: shell description: pam_pwhistory line and its options in common-password. spec: script: | l=$(grep -E '^[[:space:]]*password[[:space:]].*pam_pwhistory\.so' /etc/pam.d/common-password) \ || { echo "pam_pwhistory not enabled"; exit 1; } echo "$l" r=$(printf '%s\n' "$l" | sed -n 's/.*remember=\([0-9]*\).*/\1/p') [ "${r:-0}" -ge "$CB_REMEMBER" ] && printf '%s\n' "$l" | grep -q enforce_for_root && printf '%s\n' "$l" | grep -q use_authtok remediation: manual: | 1. Create `/usr/share/pam-configs/cirsec_pwhistory`: ``` Name: CIRSEC - password history (pam_pwhistory) Default: yes Priority: 1000 Password-Type: Primary Password: requisite pam_pwhistory.so remember={{ remember }} enforce_for_root try_first_pass use_authtok ``` 2. Run `pam-auth-update --enable cirsec_pwhistory`. effects: restart: none disruption: low lockout_risk: false rollback: | Run `pam-auth-update --remove cirsec_pwhistory` and delete the profile file. scripts: - id: configure engine: shell content: | p=/usr/share/pam-configs/cirsec_pwhistory printf '%s\n' 'Name: CIRSEC - password history (pam_pwhistory)' 'Default: yes' 'Priority: 1000' \ 'Password-Type: Primary' 'Password:' \ " requisite pam_pwhistory.so remember=$CB_REMEMBER enforce_for_root try_first_pass use_authtok" >"$p" cb_backup /etc/pam.d/common-password DEBIAN_FRONTEND=noninteractive pam-auth-update --enable cirsec_pwhistory references: - title: pam_pwhistory(8), Debian manual pages url: https://manpages.debian.org/trixie/libpam-runtime/pam_pwhistory.8.en.html publisher: Debian kind: vendor-doc accessed: 2026-10-18 - title: pam-auth-update(8), Debian manual pages url: https://manpages.debian.org/trixie/libpam-runtime/pam-auth-update.8.en.html publisher: Debian kind: vendor-doc accessed: 2026-10-18 mappings: - framework: nist-800-53r5 framework_version: "5.1.1" id: IA-5(1) relation: partial - framework: cis-debian-12 framework_version: "2.0.0" id: "5.3.2.4" relation: partial - framework: cis-debian-12 framework_version: "2.0.0" id: "5.3.3.3.1" relation: equivalent - framework: cis-debian-12 framework_version: "2.0.0" id: "5.3.3.3.2" relation: equivalent - framework: cis-debian-12 framework_version: "2.0.0" id: "5.3.3.3.3" relation: equivalent - framework: cis-debian-13 framework_version: "1.1.0" id: "5.3.2.4" relation: partial - framework: cis-debian-13 framework_version: "1.1.0" id: "5.3.3.3.1" relation: equivalent - framework: cis-debian-13 framework_version: "1.1.0" id: "5.3.3.3.2" relation: equivalent - framework: cis-debian-13 framework_version: "1.1.0" id: "5.3.3.3.3" relation: equivalent threats: - framework: mitre-attack id: T1110 related_controls: - id: CB-DEB-AUTH-010 type: related authors: - name: Alice github: Sn0wAlice verified: - date: 2026-10-18 by: Sn0wAlice versions: ["12"] environment: Proxmox VM, Debian 12 genericcloud image, kernel 6.1.0-54-cloud-amd64 notes: Reuse of the last password rejected with pamtester. - date: 2026-10-18 by: Sn0wAlice versions: ["13"] environment: Proxmox VM, Debian 13 genericcloud image, kernel 6.12.113+deb13-cloud-amd64 notes: Reuse of the last password rejected with pamtester. introduced_in: 0.1.0 created: 2026-10-18 updated: 2026-10-18