Ensure the Default Umask is Set Correctly in login.defs
Ensures the UMASK directive in /etc/login.defs sets a restrictive default umask (at least as strict as 0027/0077 per norm) for all login sessions.
Checked against the content of a persistent configuration file, the source of truth that survives reboots.
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
The umask determines the permissions stripped from newly created files and directories. The UMASK directive in /etc/login.defs is the value the login process and PAM (pam_umask) hand to a session at sign-in, so it sets the baseline for every login method (console, ssh, su, cron), independent of which shell rc files exist. If left permissive, files are created group- or world-readable/writable by default. Setting it at least as strict as 0027 (CIS) / 0077 (ANSSI BP-028 R36) enforces least privilege at the source of the session.
What Pavois checks
Pavois reads the last effective UMASK line in /etc/login.defs and tests it against the norm target with a bitmask comparison ((value & mask) == mask), so 0077 satisfies 0027. login.defs is the most authoritative of the umask sources because, via pam_umask, it governs non-shell logins too (cron, su, graphical sessions) that never read bash.bashrc or /etc/profile - making the effective default predictable regardless of the user's shell. Taking tail -1 honors the last-wins semantics of the file.
m = {'bp28'=>'0077','cis'=>'0027'}.fetch(input('pavois_standard', value: '_default'), '0077')
describe command("v=$(grep -hiE '^[[:space:]]*UMASK[[:space:]]+[0-7]+' /etc/login.defs 2>/dev/null | grep -oE '[0-7]+' | tail -1); { [ -n \"$v\" ] && [ $((0$v & #{m})) -eq $((#{m})) ] && echo ok; } || echo ko") do
its('stdout.strip') { should eq 'ok' }
endHow to verify it is applied
Inspect the configured directive:
grep -hiE '^[[:space:]]*UMASK[[:space:]]+[0-7]+' /etc/login.defs | tail -1
Expected UMASK 027 (or stricter, e.g. 077). For the value a login actually applies, check a fresh non-interactive login session, e.g. su - <user> -c umask.
Inspect & investigate
umask has no audit event; verify it from current state. Show the directive with grep -i umask /etc/login.defs. Confirm pam_umask is in effect via grep -r pam_umask /etc/pam.d/, and observe the value a real login inherits with su - <user> -c umask.
Remediation
No automated harden plan is wired for this rule (remediation is empty), so it must be applied manually: set or correct the UMASK 027 directive (or UMASK 077 for ANSSI) in /etc/login.defs, ensuring it is the last/effective UMASK line. New logins inherit it immediately; existing sessions must re-login.
Pavois applies this with its own harden engine, the plan below, not a shell script:
| file | /etc/login.defs |
|---|---|
| key | UMASK |
| resource | conf_line |
| sep | space |
| value | 077 |
pavois harden plan localwhere the target is local, a user@host SSH alias, or a container , Docs
Impact & precautions
Low risk but broad reach: because login.defs/pam_umask affects every login path, a too-strict value silently removes group access from files created by cron jobs, service accounts and shared workflows, which can break collaborative directories or web stacks that expect 0664/0775. Before enforcing fleet-wide, audit such workflows; where group sharing is required, use setgid directories + ACLs rather than loosening the global default. The change touches only new files and is fully reversible by editing the directive.
Standards mapping
| Standard | Reference | Type | Version | Confidence |
|---|---|---|---|---|
| ANSSI BP-028 | R36 | direct | 2.0 | high |
| CIS | 5.4.3.3 | direct | per OS, see the benchmark table | high |
| NIST | AC-6(1), CM-6(a) | supporting | 800-53 Rev 5 · 800-171 Rev 2 (pinned) | medium |
| DISA STIG | UBTU-22-412035, UBTU-24-300030 | direct | per OS STIG release | high |
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.