File and Directory Permissions
Inspect parent directories, ACLs, mount options, file capabilities, and SUID/SGID in addition to the target file. If a root process reads the path, investigate further under Writable Paths Read by root.
Commands to check
Section titled “Commands to check”Additional check examples:
namei -l <path>stat <path>ls -la <path>findmntgetfacl <path>getcap <file>getcap -r / 2>/dev/nullfind / -perm -4000 -type f 2>/dev/nullfind / -perm -2000 -type f 2>/dev/null- Purpose: Check owners, groups, modes, ACLs, symlinks, mount options, capabilities, and SUID/SGID.
- Prerequisites: Searching every filesystem is expensive. Start with
/opt,/srv,/var/www,/home/<user>,/etc/systemd/system,/usr/local/bin, and application directories. - What to inspect: Writable parent directories,
nosuid,noexec,nodev, bind mounts, and user-writable paths read by root processes. - Expected output:
drwxrwxr-x root <group> ... <app>/plugins,/tmpwithoutnosuid, or a shared path mounted with bind. - Interpretation: Even when root owns a file, a writable parent directory may allow replacement, symlinks, or races. A SUID shell on a
nosuidmount will not work. - If a check fails: Inspect ACLs, supplementary groups, UID/GID inside containers, mount namespaces, and resolved symlink targets.
- Alternative commands:
find <DIR> -maxdepth 4 -writable -ls,find <DIR> -xtype l -ls,readlink -f <path>. - State change: Read-only.
find /creates load and many Permission denied messages; narrow the scope.
High-priority locations:
find /opt /srv /var/www /usr/local -maxdepth 5 -type d -writable -ls 2>/dev/nullfind /opt /srv /var/www /usr/local -maxdepth 5 -type f -writable -ls 2>/dev/nullfind /home -maxdepth 4 -type f \( -name '*.conf' -o -name '*.env' \) 2>/dev/nullShared mounts also affect container boundaries. Check them alongside findmnt in Containers and Namespaces.
Interpretation
Section titled “Interpretation”- A path read by root becomes a privilege boundary if symlinks, writable parents, races, or archive extraction affect it.
- SUID binaries do not work on
nosuidmounts.bashdrops privileges on execution without-p. - Record
getcapresults separately from the processCapEffchecked under Containers and Namespaces. File capabilities and a process’s effective capabilities are different.
Examples where permission differences create boundaries:
- If a script running as root calls
site.addsitedir()on a group-writable plugin directory, that group can write to the import path. - A symlink into a log directory may have multiple levels. A privileged viewing process might read the second-level target as root.
- On a mount shared by container and host,
chmodinside the container can change whether a host user may write. - If the Web process user can write to a theme or public directory, writing there can lead to code execution as that user.
- If output is saved as a script in the document root of a development HTTP server running as root, it executes with that process’s privileges.
The flow by which a privileged process reads these paths is diagrammed under Trust Boundaries in Custom Code.

