← All rules
SOCLE-CLD-FSP-154// File permissionsmediumpersistent config

Verify /boot/grub2/grub.cfg Permissions

Ensures /boot/grub2/grub.cfg is readable and writable only by root, protecting boot parameters and any GRUB password hash from disclosure or tampering.

Checked against the content of a persistent configuration file, the source of truth that survives reboots.

A pass proves? running now✓ on disk✓ survives rebootthe qualified verdict →
Debian 12CIS 1.1.0Debian 13CIS 1.0.0FedoraRHEL 10 / Rocky 10 / AlmaLinux 10RHEL 8 / Rocky 8 / AlmaLinux 8CIS 4.0.0RHEL 9 / Rocky 9 / AlmaLinux 9CIS 2.0.0Ubuntu 22.04CIS 3.0.0Ubuntu 24.04CIS 1.0.0Ubuntu 26.04
One check, maps to 4 standards

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

/boot/grub2/grub.cfg defines the boot-time parameters of the system: kernel command line, boot entries and, when configured, the GRUB superuser password hash. If a non-privileged user can read it, the GRUB password hash may be exposed for offline cracking; if they can write it, they can inject kernel boot arguments (e.g. init=/bin/bash or selinux=0) to bypass security controls at boot. Restricting it so only root can read and write (no read/write/execute for group or other) ensures only the administrator controls boot parameters.

What Pavois checks

Pavois reads the effective inode mode of /boot/grub2/grub.cfg and asserts no read/write/execute for group or other and no setuid/setgid/sticky bits. Guarded by only_if { file('/boot/grub2/grub.cfg').exist? } (this path is the RHEL/Fedora layout; Debian/Ubuntu BIOS systems use /boot/grub/grub.cfg, EFI systems /boot/efi/EFI/<distro>/grub.cfg). Checking the live file rather than the generator templates ensures the actually-deployed bootloader config is protected.

only_if { file('/boot/grub/grub.cfg').exist? }
describe file('/boot/grub/grub.cfg') 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 }
end

How to verify it is applied

Run stat -c '%a %U %G' /boot/grub2/grub.cfg. The expected output is 600 root root (or 700 on some EFI layouts): no read, write or execute bit for group or other.

Inspect & investigate

stat /boot/grub2/grub.cfg shows the current mode. Modifications appear in /var/log/audit/audit.log if a watch is set (grep name="/boot/grub2/grub.cfg"). Note that grub2-mkconfig regenerates the file and may reset its mode, so re-verify after kernel updates.

Remediation

No automated harden plan is defined for this rule yet, so apply it manually: chown root:root /boot/grub2/grub.cfg then chmod 0600 /boot/grub2/grub.cfg. On EFI systems adjust the path accordingly.

Pavois applies this with its own harden engine, the plan below, not a shell script:

mode0600
path/boot/grub/grub.cfg
resourcefile
pavois harden plan local

where the target is local, a user@host SSH alias, or a container , Docs

Impact & precautions

A readable grub.cfg exposes the GRUB password hash to offline cracking; a writable one lets an attacker with local file access alter the kernel command line to bypass authentication at boot (init=/bin/bash) or disable LSMs. Precautions: restricting to 0600 root:root is safe and is the distro default; do not change ownership away from root, and remember that running grub2-mkconfig/update-grub after a kernel update may regenerate the file and reset its permissions, re-apply if needed.

Standards mapping

StandardReferenceTypeVersionConfidence
ANSSI BP-028R29direct2.0high
CIS1.4.2, 2.2.6directper OS, see the benchmark tablehigh
NIST3.4.5, AC-6(1), CM-6(a)supporting800-53 Rev 5 · 800-171 Rev 2 (pinned)medium
PCI DSS2.2.6supporting4.0.1medium

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.

Sources & references