F-7.5: Squash Misconfiguration: anonuid/anongid and all_squash Pitfalls¶
Classification¶
- Severity: Critical
- CVSS Vector: Network / Low Complexity / No Auth Required
- Affected Versions: NFSv2, NFSv3 (Linux, Solaris, FreeBSD)
- Prerequisite: Network access to NFS server
Summary¶
NFS squash options (root_squash, all_squash, no_root_squash, no_all_squash) control how client-supplied UIDs/GIDs are mapped on the server. Several common misconfigurations weaken or eliminate these protections. The anonuid/anongid parameters — which set the mapped identity for squashed users — can introduce privilege escalation when set to privileged UIDs.
Technical detail¶
Squash matrix¶
| Setting | UID 0 | Non-root UIDs | Notes |
|---|---|---|---|
root_squash (default) |
Mapped to nobody (65534) |
Trusted as-is | Only protects root |
no_root_squash |
Trusted as-is | Trusted as-is | Full trust — critical |
all_squash |
Mapped to anonuid |
Mapped to anonuid |
All users become one identity |
no_all_squash (default) |
Per root_squash |
Trusted as-is | Default behavior |
Misconfiguration 1: anonuid=0¶
The administrator intended all_squash to be safe — "everyone is the same user." But by setting anonuid=0, that user is root. Every connection gets root access.
Misconfiguration 2: anonuid set to service account¶
All NFS users become www-data — which may have write access to web roots, application configs, and other sensitive paths.
Misconfiguration 3: no_all_squash is the default¶
On Linux, the default squash behavior is root_squash,no_all_squash:
- UID 0 → mapped to nobody (safe)
- UID 1-65533 → trusted as client reports (unsafe)
Many administrators believe root_squash protects them, but non-root UIDs are still completely attacker-controlled.
Misconfiguration 4: insecure + no_root_squash¶
The FOG Project's default exports configuration demonstrated this:
insecure removes the privileged port check. no_root_squash trusts UID 0. Combined: anyone on the network gets root access from any port.
Exploitation¶
# Detect anonuid/anongid values
# These appear in /etc/exports on the server — not directly queryable via NFS
# But the effect is observable: mount with all_squash and check resulting UID
# Create a file via NFS
touch /mnt/nfs/test_squash
ls -la /mnt/nfs/test_squash
# If owner is root:root → anonuid=0 (critical misconfiguration)
# If owner is www-data:www-data → anonuid=33 (service account access)
# If owner is nobody:nogroup → safe default (65534)
Detecting from outside¶
# analyze runs this probe automatically: it writes a temp file as a high UID,
# reads back the resulting ownership, infers the anonuid mapping, then cleans up.
nfswolf --uid 99999 analyze target:/data
# Manual equivalent in a write-enabled shell:
nfswolf --uid 99999 --gid 99999 shell target:/data --allow-write
nfs> put /etc/hostname .squash_test # write a probe file
nfs> stat .squash_test # owner reveals the anonuid mapping
nfs> rm .squash_test
Impact¶
anonuid=0: Full root access for all connectionsanonuid=<service>: Access as a potentially privileged service accountno_all_squash+root_squash: False sense of security — only root is protected- Combined with
insecure: No port restriction, potentially no UID restriction
Detection (nfswolf)¶
nfswolf analyze performs:
1. Create a test file and check resulting ownership (reveals anonuid)
2. Try UID 0 write (detects no_root_squash)
3. Try arbitrary UID write (detects no_all_squash — always true by default)
4. Report the effective squash configuration per export
Remediation¶
- Never set
anonuid=0oranongid=0— use 65534 (nobody) or a dedicated unprivileged UID - Use
all_squashwhen possible to eliminate UID trust entirely - If
all_squashis used, ensureanonuidpoints to an unprivileged, purpose-specific user with no shell - Never combine
insecurewithno_root_squash - Use Kerberos (
sec=krb5) to eliminate the squash question entirely