F-2.9: WebNFS Public File Handle (MOUNT Bypass)¶
Classification¶
- Severity: Critical
- CVSS Vector: Network / Low Complexity / No Auth Required
- Affected Versions: NFSv2, NFSv3 (servers with WebNFS enabled)
- RFC Reference: RFC 2054 §5, RFC 2055 §5, RFC 2055 §6.3, RFC 2055 §10, RFC 2224 §9, RFC 2623 §2.6
- Prerequisite: Server has WebNFS enabled (Solaris
publicshare option, NetAppnfs.webnfs.enable, embedded RTOS)
Summary¶
WebNFS defines a well-known "public" file handle that any client can construct and use without the MOUNT protocol. For NFSv3, the public handle is zero-length; for NFSv2, it is 32 bytes of zeros. A client presenting this handle bypasses all MOUNT-layer access control: export ACLs, hostname restrictions, privileged-port checks, and auth flavor negotiation. Combined with multi-component LOOKUP, a single RPC can traverse the entire server filesystem tree.
Technical detail¶
The public file handle¶
Per RFC 2054 §5:
"A WebNFS client can use the public filehandle as an initial filehandle rather than using the MOUNT protocol."
- NFSv3: Zero-length handle (the
fhandle3opaque with length 0) - NFSv2: 32 bytes of all zeros (the fixed
fhandletype)
RFC 2623 §2.6 explicitly warns: "WebNFS clients that use the public file handle lookup will not go through the MOUNT protocol to acquire initial file handle of the NFS file system. Enforcing access control via the MOUNT protocol is going to be of little use."
Multi-component LOOKUP (MCL)¶
When used with the public handle, LOOKUP accepts a full pathname instead of a single component (RFC 2054 §6.1):
- Absolute paths starting with "/" are "evaluated relative to the server's root directory" -- not the export root. A single
LOOKUP 0x0 "/etc/shadow"reaches the absolute filesystem root if the server supports it. - Relative paths with ".." traverse upward. RFC 2224 §9 warns: "a path that includes multiple occurrences of '../' may locate a filesystem outside of the exported filesystem associated with the public filehandle."
- Export-spanning: RFC 2055 §6.3 states the server may cross export boundaries during MCL evaluation, unlike regular LOOKUP which is restricted from crossing mountpoints.
- Symlink resolution: The server evaluates symlinks inline during MCL (RFC 2055 §6.2), which could be exploited for further traversal.
MOUNT bypass impact¶
The public handle bypasses every layer of MOUNT-based access control:
| MOUNT Protection | Bypassed? | Why |
|---|---|---|
| Export ACLs (IP/hostname) | Yes | MOUNT is never called; handle is well-known |
| Auth flavor negotiation | Yes | No MNT response → no auth_flavors list |
| Privileged port check | Yes | Port check is on mountd, not nfsd |
| Export path validation | Yes | MCL with "/" starts at server root |
WebNFS security negotiation (RFC 2755)¶
The SNEGO-MCL protocol (RFC 2755) allows unauthenticated enumeration of security mechanisms:
- A LOOKUP with a 0x81 prefix byte returns the complete array of security mechanisms the server accepts for a path
- No authentication required for the negotiation itself (RFC 2755 §5: "no mandatory security mechanisms are specified")
- AUTH_TOOWEAK responses confirm path existence and reveal stronger auth requirements
Attack flow¶
1. Send GETATTR with zero-length handle (NFSv3) or all-zero handle (NFSv2)
→ NFS3_OK confirms WebNFS is enabled
2. Send LOOKUP with public handle + canonical path "/etc/shadow"
→ Returns file handle for /etc/shadow (absolute path, bypasses export root)
3. READ the returned handle with GID 42 (Debian shadow group)
→ Password hashes extracted in two RPCs, no MOUNT needed
Impact¶
- Complete MOUNT bypass: No export ACL, no hostname check, no port check
- Server root traversal: Absolute paths reach the entire filesystem
- Single-RPC exploitation: MCL + READ = two RPCs from zero knowledge to data extraction
- Invisible to mountd: No MOUNT calls means no
rmtabentries, noshowmountvisibility - Strengthens F-2.7: Handles obtained via public handle work as bearer tokens from any IP
Detection (nfswolf)¶
The analyzer checks (src/engine/analyzer.rs):
1. GETATTR with zero-length handle (NFSv3) and all-zero handle (NFSv2)
2. On success, attempts multi-component LOOKUP for "etc/shadow" on both versions
3. Reports as Critical when the public handle is accepted
Remediation¶
- Disable WebNFS -- most servers do not need it:
- Solaris: remove
publicoption from share - NetApp:
nfs.webnfs.enable off - Linux knfsd: does not support WebNFS (not vulnerable)
- Use Kerberos (
sec=krb5) -- the public handle still reaches nfsd, but Kerberos prevents UID spoofing for file access - Network segmentation -- restrict access to NFS port 2049
Related findings¶
| Finding | Relationship |
|---|---|
| F-2.1: Export Escape | Export escape via handle construction; WebNFS achieves the same result without construction |
| F-2.7: NFS Daemon ACL Blindness | Root cause -- nfsd never validates that the handle was issued by mountd |
| F-5.1: Export List Enumeration | MOUNT EXPORT reveals ACLs; WebNFS bypasses MOUNT entirely |