Description
/etc/passwd is world-readable and must only contain x in the password field; the hashes
belong in /etc/shadow, readable by root and the shadow group only. In /etc/shadow, each
password field holds a hash, or !/* for locked accounts, but is never empty.
Rationale
A hash left in /etc/passwd can be copied and cracked by any local user. An empty password
field lets anyone log in to the account where empty passwords are accepted.
Impact
None for a standard system.
Audit
awk -F: '$2 != "x"' /etc/passwdprints nothing.awk -F: '$2 == ""' /etc/shadowprints nothing.
Automated: every check must pass. Scanners report each check by its id.
shadowed
script: |
u=$(awk -F: '$2 != "x" {print $1}' /etc/passwd | tr '\n' ' ')
echo "not shadowed: ${u:-none}"
[ -z "$u" ]
not-empty
script: |
u=$(awk -F: '$2 == "" {print $1}' /etc/shadow | tr '\n' ' ')
echo "empty password: ${u:-none}"
[ -z "$u" ]
Remediation
- Run
pwconvto move any hash from/etc/passwdto/etc/shadow. - Lock each account with an empty password (
passwd -l <user>) or give it one (passwd <user>).
| Restart | none |
| Disruption | low |
Rollback
Restore /etc/passwd and /etc/shadow from the backup.
fix
cb_backup /etc/passwd
cb_backup /etc/shadow
pwconv
for u in $(awk -F: '$2 == "" {print $1}' /etc/shadow); do passwd -l "$u" >/dev/null; done
Handwritten code reads parameters from CB_<NAME> environment variables. Each release turns these fixes into remediate.sh and an Ansible role per profile: dry run by default, a fix runs only when its check fails.
References
- shadow(5), Debian manual pages Debian, vendor-doc, accessed 2026-10-18
- ANSSI-BP-028 v2.0 - Recommandations de configuration d'un système GNU/Linux (R68) ANSSI, guide, accessed 2026-10-18
Mappings
| Framework | ID | Relation |
|---|---|---|
| ANSSI-BP-028 - Recommandations de configuration d'un système GNU/Linux2.0 | R68 | partial |
| NIST SP 800-53 Rev. 55.1.1 | IA-5(1) | related |
How this control relates to the other framework's: equivalent, stricter, looser, partial or related.
Threats mitigated
| Taxonomy | ID |
|---|---|
| MITRE ATT&CK | T1003.008 |
People and lifecycle
| Authors |
|
| Verified | 2026-10-18 by Sn0wAlice on 12, Proxmox VM, Debian 12 genericcloud image, kernel 6.1.0-54-cloud-amd64. Generated check, fix and check again for profiles core and server-hardened; state kept after reboot. |
| Verified | 2026-10-18 by Sn0wAlice on 13, Proxmox VM, Debian 13 genericcloud image, kernel 6.12.113+deb13-cloud-amd64. Generated check, fix and check again for profiles core and server-hardened; state kept after reboot. |
| Introduced in | v0.1.0 |
| Created, updated | 2026-10-18, 2026-10-18 |
| Translations | fr |