All GRUB configuration files must have mode 0600 or more restrictive
Ensures the GRUB2 configuration under /boot/grub2 is not group/other-readable or writable and carries no executable or special (setuid/setgid/sticky) bits, i.e. mode 0600 or stricter.
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 GRUB2 configuration under /boot/grub2 (notably grub.cfg and user.cfg) controls how the system boots and may store the GRUB bootloader password hash. If it is group/other-readable, that hash can be extracted and cracked offline to defeat boot-time protection; if it is writable, an attacker could inject kernel boot parameters (e.g. init=/bin/bash) to gain root at the next reboot. Mode 0600, owned by root, keeps boot settings confidential and immutable to non-root users.
What Pavois checks
Pavois reads the live mode bits of /boot/grub2 via the InSpec file resource, the permissions the kernel enforces, instead of a packaging default. A regenerated grub.cfg (after grub2-mkconfig) can be re-created with looser permissions, which this catches. The only_if guard skips the check on systems where /boot/grub2 is absent (e.g. UEFI-only layouts using /boot/efi).
only_if { file('/boot/grub2').exist? }
describe file('/boot/grub2') do
it { should_not be_executable.by('owner') }
it { should_not be_setuid }
it { should_not be_executable.by('group') }
it { should_not be_writable.by('group') }
it { should_not be_readable.by('group') }
it { should_not be_setgid }
it { should_not be_executable.by('other') }
it { should_not be_writable.by('other') }
it { should_not be_readable.by('other') }
it { should_not be_sticky }
endHow to verify it is applied
Run stat -c '%a %U %G %n' /boot/grub2/grub.cfg /boot/grub2/user.cfg 2>/dev/null. Expected output shows 600 root root (or stricter) for each existing file, with no group/other access.
Inspect & investigate
GRUB config is rebuilt by grub2-mkconfig/grubby; their runs appear in your package/transaction history (dnf history) or shell logs. Boot-time GRUB authentication events are visible in the console and, after boot, in journalctl -b. Track permission changes with an auditd watch and grep grub2 /var/log/audit/audit.log.
Remediation
No automated remediation is defined, so apply it manually: chown root:root /boot/grub2/grub.cfg /boot/grub2/user.cfg && chmod 0600 /boot/grub2/grub.cfg /boot/grub2/user.cfg. If you regenerate the config with grub2-mkconfig -o /boot/grub2/grub.cfg, re-check the mode afterwards.
Pavois applies this with its own harden engine, the plan below, not a shell script:
| mode | 0600 |
|---|---|
| path | /boot/grub2 |
| resource | file |
pavois harden plan localwhere the target is local, a user@host SSH alias, or a container , Docs
Impact & precautions
Risk if not applied: a readable GRUB config leaks the bootloader password hash; a writable one lets an attacker boot into a root shell. Precautions: setting mode 0600 is non-disruptive, GRUB reads its config in the early-boot environment before DAC applies, and only root edits it at runtime. Do not place /boot/grub2 on a filesystem mounted with restrictive ACLs that block root, and remember that a GRUB superuser password must be paired with --unrestricted on normal menu entries or every boot will halt at the GRUB prompt.
Standards mapping
| Standard | Reference | Type | Version | Confidence |
|---|---|---|---|---|
| CIS | 1.4.2 | direct | per OS, see the benchmark table | 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.