Verify Permissions on /etc/cron.allow file
Ensures /etc/cron.allow is not writable or readable by group/other and carries no setuid/setgid/sticky or execute bits, so only the owner (root) controls who may schedule cron jobs.
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
/etc/cron.allow is the allow-list that decides which users may submit cron jobs. If its permissions are not 0640 or more restrictive, an unauthorized user could read the list (information disclosure) or, worse, modify it to grant themselves cron access. Any command they then schedule runs under cron, often as a privileged user, opening a path to privilege escalation and persistence.
What Pavois checks
Pavois reads the actual file metadata with file('/etc/cron.allow') and asserts the absence of insecure mode bits (no group/other write, no other read, no setuid/setgid/sticky/exec). It is gated by only_if so it is skipped when the file does not exist. Inspecting the live inode reflects the effective permissions on disk, including any change made out-of-band by a package, script or operator, rather than a value assumed from a config template.
only_if { file('/etc/cron.allow').exist? }
describe file('/etc/cron.allow') 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_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' /etc/cron.allow. Expected: mode 640 (or stricter, e.g. 600), owner root, group root, no read/write for other, no write for group, and no setuid/setgid/sticky bit.
Inspect & investigate
There is no service log for file permissions; inspect the file directly with stat /etc/cron.allow or ls -l /etc/cron.allow. Changes to the file can be tracked if auditd watches it, e.g. auditctl -w /etc/cron.allow -p wa then grep /var/log/audit/audit.log for the rule key.
Remediation
No automated remediation is defined for this rule, so it must be applied manually: chown root:root /etc/cron.allow && chmod u-x,g-wx,o-rwx /etc/cron.allow (resulting mode 640 or stricter). Re-run the scan to confirm the rule passes.
Pavois applies this with its own harden engine, the plan below, not a shell script:
| mode | 0600 |
|---|---|
| path | /etc/cron.allow |
| resource | file |
pavois harden plan localwhere the target is local, a user@host SSH alias, or a container , Docs
Impact & precautions
Risk if left misconfigured: an attacker who can read /etc/cron.allow learns which accounts may run cron, and one who can write it grants themselves scheduled-task execution, a classic persistence and privilege-escalation vector. Precautions: tightening permissions on this file is non-disruptive; cron continues to read it as root regardless. Just confirm the file is owned by root:root before removing group/other access so you do not accidentally lock cron management out for legitimate tooling that relies on group read.
Standards mapping
| Standard | Reference | Type | Version | Confidence |
|---|---|---|---|---|
| CIS | 2.2.6, 2.4.1.8, 2.4.1.9 | direct | per OS, see the benchmark table | high |
| PCI DSS | 2.2.6 | 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.