Debian GNU/Linux · Accounts & authentication

Set a restrictive default umask for login sessions

When it fails: New files are readable by every local user by default. With the Debian default umask, documents, exports and logs created by users and root are world-readable.

CB-DEB-AUTH-019lowactiveautomatedautomated fixprofile core

Description

The umask removes permission bits from every file and directory a process creates. Debian login sessions get 022 (files 644, everyone can read them); on Debian 13, pam_umask with USERGROUPS_ENAB even gives regular users 002. This control sets {{ umask }} from /etc/profile.d/, which applies to the login shells of every user, root included.

Services started by systemd do not read /etc/profile; set their umask with UMask= in their unit.

Rationale

Users and administrators regularly create files with sensitive content (exports, dumps, configuration copies) in their home or in /tmp. A restrictive umask keeps them private unless someone opens them on purpose.

Impact

Files created in shared directories are no longer readable by other users. Teams that share files through a common group need chmod g+r or a setgid group directory.

Setting

Location/etc/profile.d/60-cirsec-umask.sh
Default022
Recommended{{ umask }}

Parameters

ParameterCoreServerServer hardenedDesktopDesktop hardenedBounds
umaskenum. Default umask of login shells.027027077027027one of 027, 077

The value used is your override (tailoring file), else the profile's, else the one of the profile it extends, else the default. Bounds limit what an override may set.

Audit

Run su -s /bin/sh -l nobody -c umask and su -l root -c umask. Both must print 0{{ umask }} (or a stricter value).

Automated: every check must pass. Scanners report each check by its id.

user

Umask of a login shell for a regular account.

script: |
  u=$(su -s /bin/sh -l nobody -c umask 2>/dev/null | tail -n 1) || exit 3
  echo "nobody login umask: $u"
  [ $(( 0$u & 0$CB_UMASK )) -eq $(( 0$CB_UMASK )) ]

root

Umask of a root login shell.

script: |
  u=$(su -l root -c umask 2>/dev/null | tail -n 1) || exit 3
  echo "root login umask: $u"
  [ $(( 0$u & 0$CB_UMASK )) -eq $(( 0$CB_UMASK )) ]

Remediation

Create /etc/profile.d/60-cirsec-umask.sh containing umask {{ umask }}. New login sessions pick it up.

Restartusers must log in again
Disruptionlow

Rollback

Delete /etc/profile.d/60-cirsec-umask.sh.

profile

f=/etc/profile.d/60-cirsec-umask.sh
cb_backup "$f"
printf '%s\n' '# Written by CIRSEC Baselines CB-DEB-AUTH-019' "umask $CB_UMASK" >"$f"
chmod 644 "$f"

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

Mappings

How this control relates to the other framework's: equivalent, stricter, looser, partial or related.

Threats mitigated

People and lifecycle

Authors
Verified2026-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.
Verified2026-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 inv0.1.0
Created, updated2026-10-18, 2026-10-18
Translationsfr