Skip to content

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

/etc/exports:
/data  *(rw,all_squash,anonuid=0,anongid=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

/etc/exports:
/images  *(rw,all_squash,anonuid=33,anongid=33)   # www-data

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:

/images *(ro,sync,no_wdelay,no_subtree_check,insecure_locks,no_root_squash,insecure)

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 connections
  • anonuid=<service>: Access as a potentially privileged service account
  • no_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

  1. Never set anonuid=0 or anongid=0 — use 65534 (nobody) or a dedicated unprivileged UID
  2. Use all_squash when possible to eliminate UID trust entirely
  3. If all_squash is used, ensure anonuid points to an unprivileged, purpose-specific user with no shell
  4. Never combine insecure with no_root_squash
  5. Use Kerberos (sec=krb5) to eliminate the squash question entirely