Ensure shadow Group is Empty
Ensures the shadow group has no members, so no user gains read access to /etc/shadow and its password hashes.
Checked against what is installed or registered, packages present/absent, account databases.
A mapping is a cross-reference to where each standard places this requirement, anchored and cross-validated, not a claim of equivalence. A passing check is evidence toward these references, how to read it.
Why this rule matters
On Debian/Ubuntu the /etc/shadow file is group-owned by shadow and readable by that group. Any user placed in the shadow group therefore gains read access to every account's hashed password and password-aging data. With that file in hand, an attacker can run an offline password-cracking tool against the hashes and use the aging/expiry fields to target additional accounts. The shadow group is meant to be used by daemons (via setgid binaries), not by people, so it should contain no members.
What Pavois checks
Pavois inspects the member field of the shadow entry as resolved on the live system. Reading the effective group membership matters because a user can also be in shadow as their primary group or via an NSS backend; the goal state is that no human account lists shadow among its supplementary groups.
describe command('awk -F: \'($1=="shadow"){print $4}\' /etc/group') do
its('stdout.strip') { should eq '' }
endHow to verify it is applied
List the shadow group and confirm the member field is empty:
getent group shadow, expected output ends with an empty field, e.g.shadow:x:42:(nothing after the last colon).awk -F: '($1=="shadow"){print $4}' /etc/group, expected output is empty.
Inspect & investigate
Group membership changes are recorded by user-management tooling:
grep -E 'shadow' /var/log/auth.log, showsusermod/gpasswdactions touching the shadow group.getent group shadowis the authoritative current-state command; compare it before and after any change.
Remediation
No automated harden plan is defined for this rule yet, so it must be applied manually: remove every user from the shadow group with gpasswd --delete <user> shadow (and fix any account whose primary group is shadow with usermod -g <other> <user>) until getent group shadow shows no members.
Pavois applies this with its own harden engine, the plan below, not a shell script:
| command | getent group shadow # gpasswd -d <user> shadow for each unexpected member |
|---|---|
| reason | removing members from the shadow group is deliberate (they lose shadow access) |
| resource | manual |
pavois harden plan localwhere the target is local, a user@host SSH alias, or a container , Docs
Impact & precautions
Risk if not applied: any shadow-group member can read every password hash on the host, enabling offline cracking and lateral movement.
Precautions before applying: check why each member was added, some legacy tools or monitoring agents may rely on shadow read access. Move those to a dedicated setgid helper or grant access narrowly instead of leaving humans in the group. Removing members is non-disruptive to login itself, since /etc/shadow reads by PAM happen as root, not via the group.
Standards mapping
| Standard | Reference | Type | Version | Confidence |
|---|---|---|---|---|
| CIS | 7.2.4, 8.3.2 | direct | per OS, see the benchmark table | high |
| PCI DSS | 8.3.2 | supporting | 4.0.1 | medium |
Each reference is a cross-reference anchored in the upstream benchmark and cross-validated against the SCAP Security Guide and ansible-lockdown, not a claim of equivalence. Direct = a prescriptive, line-level requirement; supporting = an abstract control family (NIST) the check provides evidence toward. How to read a mapping.