Verify that system commands files are group owned by root or a system account
Ensures every executable in the system command directories (/bin, /sbin, /usr/bin, /usr/sbin, /usr/local/bin, /usr/local/sbin) is group-owned by root.
Checked against a path’s metadata, mode, owner, group, SUID/SGID.
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 binaries under /bin, /sbin, /usr/bin, /usr/sbin, /usr/local/bin and /usr/local/sbin are run by privileged users and system services. If one of these files is group-owned by a non-system group, any member of that group could replace or modify the binary and have their code executed with the privileges of whoever runs it, a direct path to privilege escalation or persistence. Keeping them group-owned by root ensures only the most trusted account can alter system commands.
What Pavois checks
Pavois runs find /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin -type f ! -group root and expects empty output, any path returned is a binary with a non-root group. Scanning the actual on-disk files (not the package database) catches manually installed tools, scripts dropped into /usr/local/bin and binaries whose group was changed after installation, exactly the cases a package-manifest audit misses.
describe command('timeout 90 find /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin -type f ! -group root 2>/dev/null') do
its('exit_status') { should_not cmp 124 } # timeout killed the scan: no evidence, not a pass
its('stdout.strip') { should eq '' }
endHow to verify it is applied
Run the scan manually:
find /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin -type f ! -group root
Expected output: nothing (empty). Any printed path is a binary whose group is not root; inspect it with ls -l <file>.
Inspect & investigate
List the offenders and their group with find /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin -type f ! -group root -printf '%g %p\n'. On RPM systems, compare against the shipped metadata with rpm -Vf <file> (look for the G flag); on Debian, packaged binaries should be root by design, so a mismatch points to a local change.
Remediation
No automated harden plan is defined for this rule, so it must be applied manually. After identifying the offending files, set their group with chgrp root <file> (only for binaries that should genuinely belong to root). Investigate why the group was non-root before changing it, an unexpected owner can indicate a compromised or misinstalled binary.
Pavois applies this with its own harden engine, the plan below, not a shell script:
| command | find /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin -type f \( ! -user root -o ! -group root \) -exec chown root:root {} + 2>/dev/null; true |
|---|---|
| name | fix-bindir-ownership |
| not_if | test -z "$(find /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin -type f \( ! -user root -o ! -group root \) 2>/dev/null | head -1)" |
| resource | exec |
pavois harden plan localwhere the target is local, a user@host SSH alias, or a container , Docs
Impact & precautions
Risk if left as-is: a writable system binary lets a non-root group member hijack any privileged process that runs it. Before fixing: confirm the file is meant to be root-group-owned, a handful of third-party packages legitimately ship setgid helpers owned by a dedicated group, and blindly running chgrp root on them can break the tool or its setgid behaviour. Change ownership file by file, not with a recursive sweep, and verify the binary's integrity (rpm -Vf / known-good checksum) first.
Standards mapping
| Standard | Reference | Type | Version | Confidence |
|---|---|---|---|---|
| ANSSI BP-028 | R50 | direct | 2.0 | high |
| NIST | CM-5(6), CM-5(6).1 | supporting | 800-53 Rev 5 · 800-171 Rev 2 (pinned) | medium |
| DISA STIG | UBTU-22-232055, UBTU-24-300013 | 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.