Back to Blog
high SEVERITY8 min read

Securing rpcbind: How Unauthenticated RPC Registration Exposes NFS Infrastructure

A high-severity vulnerability was discovered in an NFS utilities configuration where rpcbind (port 111) accepted RPC service registrations without any authentication, allowing any network-accessible attacker to register malicious services under legitimate RPC program numbers and redirect NFS clients. The fix adds critical security documentation and network isolation guidance, ensuring operators understand that rpcbind must be protected by host-level firewalling or Kubernetes network policies to

O
By Orbis AppSec
Published May 28, 2026Reviewed June 3, 2026

Answer Summary

Unauthenticated RPC service registration in NFS rpcbind (CWE-306: Missing Authentication for Critical Function) allowed attackers on port 111 to register malicious services under legitimate RPC program numbers and redirect NFS clients to attacker-controlled endpoints. The fix adds critical security documentation requiring network isolation through host-level firewalls or Kubernetes NetworkPolicies to restrict rpcbind access to trusted sources only.

Vulnerability at a Glance

cweCWE-306
fixNetwork isolation documentation requiring firewall rules and Kubernetes NetworkPolicies
riskNetwork attackers can hijack NFS services and redirect clients
languageSystem Configuration (NFS/RPC)
root causerpcbind accepts RPC registrations from any network source without authentication
vulnerabilityUnauthenticated RPC Service Registration

Securing rpcbind: How Unauthenticated RPC Registration Exposes NFS Infrastructure

Introduction

If you're running NFS (Network File System) in a Kubernetes cluster or any networked environment, there's a small daemon quietly listening on port 111 that could be the weakest link in your storage security: rpcbind (formerly known as portmap).

rpcbind acts as the phone book for RPC (Remote Procedure Call) services. When an NFS client wants to mount a remote filesystem, it first calls rpcbind to ask: "Where is the NFS server listening?" rpcbind looks up the registered port and hands it back. Simple, elegant — and by default, completely unauthenticated.

This post breaks down a high-severity vulnerability (V-007) discovered in an NFS utilities deployment configuration, explains how an attacker could exploit it, and walks through the fix and best practices to harden your RPC infrastructure.


The Vulnerability Explained

What Is rpcbind and Why Does It Matter?

rpcbind is a critical component of the NFSv3 stack. It maps RPC program numbers to network port numbers, acting as a dynamic service registry. Any RPC service — NFS, NLM (Network Lock Manager), NSM (Network Status Monitor) — must register itself with rpcbind before clients can discover it.

The problem? By default, rpcbind accepts PMAP_SET registration calls from any network source without authentication.

The Core Weakness

The vulnerability was confirmed in storage/nfs-utils/rpcbind/files/services at line 3, where rpcbind is deployed and exposed on port 111 across all network interfaces. The scanner found:

  • ✗ No firewall rules restricting access to port 111
  • ✗ No TCP wrappers configuration (/etc/hosts.allow / /etc/hosts.deny)
  • ✗ No authentication mechanism for PMAP_SET calls
  • ✗ No network policy limiting which pods or hosts can reach the rpcbind port

How Could an Attacker Exploit This?

The attack is elegant in its simplicity. Here's a step-by-step exploitation scenario:

Attack Scenario: RPC Service Hijacking

1. Attacker gains network access to the cluster (e.g., via a compromised pod)
2. Attacker sends a crafted PMAP_SET packet to port 111 on the rpcbind host
3. Attacker registers their malicious process under NFS program number 100003
4. Legitimate NFS clients query rpcbind for the NFS service location
5. rpcbind returns the attacker's registered port instead of the real NFS server
6. NFS clients connect to the attacker's service and send file operation requests
7. Attacker intercepts, reads, modifies, or corrupts file data in transit

A minimal proof-of-concept registration using Python's rpc libraries might look like:

# Conceptual example — for educational purposes only
import socket
import struct

# PMAP_SET: Register a fake NFS service (program 100003) on port 9999
# This would redirect NFS clients to an attacker-controlled port
pmap_set_call = build_rpc_call(
    program=100000,      # rpcbind program number
    procedure=1,         # PMAP_SET procedure
    args={
        'prog': 100003,  # NFS program number
        'vers': 3,
        'prot': 6,       # TCP
        'port': 9999     # Attacker's malicious listener
    }
)

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('target-rpcbind-host', 111))
sock.send(pmap_set_call)
# If successful, NFS clients now get redirected to port 9999

Real-World Impact

The consequences of a successful RPC hijack are severe:

Impact Description
Data Interception Attacker reads sensitive files from NFS mounts
Data Corruption Attacker modifies files mid-transit
Denial of Service Legitimate NFS services become unreachable
Privilege Escalation Manipulated files (e.g., /etc/sudoers, SSH keys) could grant higher access
Persistence Attacker maintains access by keeping malicious service registered

In a Kubernetes environment, NFS volumes are often shared across multiple pods and namespaces. A single rpcbind compromise could affect the entire cluster's persistent storage.


The Fix

What Changed

The fix introduces a critical security notice in the README.md for the nfs-utils extension, alongside a corresponding update to rpcbind.yaml:

diff --git a/storage/nfs-utils/README.md b/storage/nfs-utils/README.md
--- a/storage/nfs-utils/README.md
+++ b/storage/nfs-utils/README.md
@@ -1,5 +1,11 @@
 # nfs-utils

+> **NOTE: Security Consideration**
+>
+> `rpcbind` listens on all network interfaces by default. This is required for remote NFS
+> clients to discover RPC services. Ensure that rpcbind is only exposed on trusted networks
+> and use host-level firewalling or Kubernetes network policies to restrict access to port 111.
+
 This extension provides `rpcbind` and `rpc.statd` daemons for NFSv3 file locking support.

Why This Matters

This fix does two important things:

  1. Acknowledges the architectural reality: rpcbind must listen broadly to serve NFS clients — you can't simply bind it to localhost. The note is honest about this constraint.

  2. Directs operators to the correct mitigation layer: Since rpcbind itself lacks built-in authentication for PMAP_SET, the defense must happen at the network layer. The fix explicitly calls this out and points to the right tools.

The Deeper Fix: Network-Level Controls

The documentation fix is the first step. The real remediation happens when operators implement the recommended network controls. Here's what that looks like in practice:

Option 1: iptables / nftables Host Firewall

# Allow rpcbind only from trusted NFS client subnet
iptables -A INPUT -p tcp --dport 111 -s 10.0.1.0/24 -j ACCEPT
iptables -A INPUT -p udp --dport 111 -s 10.0.1.0/24 -j ACCEPT

# Drop all other rpcbind traffic
iptables -A INPUT -p tcp --dport 111 -j DROP
iptables -A INPUT -p udp --dport 111 -j DROP

# Also restrict PMAP_SET (registration) to localhost only
# This prevents remote service registration entirely
iptables -A INPUT -p tcp --dport 111 ! -s 127.0.0.1 -m string \
  --algo bm --string "PMAP_SET" -j DROP

Option 2: Kubernetes NetworkPolicy

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: restrict-rpcbind
  namespace: storage
spec:
  podSelector:
    matchLabels:
      app: nfs-server
  policyTypes:
    - Ingress
  ingress:
    # Allow rpcbind only from NFS client pods
    - from:
        - podSelector:
            matchLabels:
              role: nfs-client
        - namespaceSelector:
            matchLabels:
              nfs-access: "true"
      ports:
        - protocol: TCP
          port: 111
        - protocol: UDP
          port: 111

Option 3: TCP Wrappers (Legacy but Effective)

# /etc/hosts.allow
rpcbind: 10.0.1.0/255.255.255.0  # Trusted NFS client subnet
rpcbind: 127.0.0.1               # Localhost always allowed

# /etc/hosts.deny
rpcbind: ALL                     # Deny everything else

Option 4: rpcbind -h Flag (Bind to Specific Interface)

# Start rpcbind bound only to the internal network interface
# instead of all interfaces (0.0.0.0)
rpcbind -h 10.0.1.100

# In systemd unit or container args:
ExecStart=/sbin/rpcbind -f -w -h 10.0.1.100

Prevention & Best Practices

1. Apply the Principle of Least Network Exposure

RPC services like rpcbind should never be exposed to the public internet or untrusted networks. Treat port 111 like you would a database port — strictly firewalled.

Internet → [Firewall: DENY 111] → Internal Network → [Firewall: ALLOW 111 from trusted] → NFS Host

2. Prefer NFSv4 Over NFSv3 Where Possible

NFSv4 does not use rpcbind for its primary port — it uses a well-known port (2049) directly. This eliminates the rpcbind attack surface entirely for the main data path.

# NFSv4 mount — no rpcbind dependency for the mount itself
mount -t nfs4 -o proto=tcp nfs-server:/export /mnt/data

# NFSv3 mount — requires rpcbind to be accessible
mount -t nfs -o vers=3 nfs-server:/export /mnt/data

3. Audit Registered RPC Services Regularly

Use rpcinfo to periodically verify that only expected services are registered:

# List all registered RPC services
rpcinfo -p <nfs-host>

# Expected output for a clean NFS server:
#    program vers proto   port  service
#    100000    4   tcp    111  portmapper
#    100000    3   tcp    111  portmapper
#    100003    3   tcp   2049  nfs
#    100021    1   tcp  32803  nlockmgr

# Alert if unexpected program numbers appear!

4. Use Container Security Contexts in Kubernetes

securityContext:
  runAsNonRoot: true
  readOnlyRootFilesystem: true
  capabilities:
    drop:
      - ALL
    add:
      - NET_BIND_SERVICE  # Only if binding to privileged port

5. Monitor for Anomalous PMAP_SET Calls

Set up network monitoring to alert on PMAP_SET calls originating from unexpected sources:

# Falco rule example
- rule: Unexpected RPC Service Registration
  desc: Detect PMAP_SET calls to rpcbind from non-localhost sources
  condition: >
    evt.type = connect and
    fd.sport = 111 and
    not fd.sip in (trusted_nfs_hosts)
  output: "Unexpected rpcbind connection (source=%fd.cip dest=%fd.sip)"
  priority: WARNING

Security Standards & References

This vulnerability maps to several well-known security frameworks:

Standard Reference
CWE CWE-306: Missing Authentication for Critical Function
CWE CWE-284: Improper Access Control
NIST SP 800-123: Guide to General Server Security
CIS CIS Benchmarks for Linux — Network Services Hardening
OWASP A01:2021 – Broken Access Control

Key Takeaways

The Vulnerability at a Glance

┌─────────────────────────────────────────────────────┐
│  VULNERABILITY: Unauthenticated rpcbind Registration │
│  SEVERITY: HIGH                                      │
│  FILE: storage/nfs-utils/rpcbind/files/services:3   │
│                                                      │
│  ATTACK VECTOR: Network → Port 111 → PMAP_SET        │
│  IMPACT: NFS service hijacking, data interception    │
│                                                      │
│  FIX: Document + enforce network-level restrictions  │
└─────────────────────────────────────────────────────┘

What We Learned

  1. Protocol-level authentication gaps require network-level mitigations. When a protocol doesn't support authentication natively, your defense-in-depth strategy must compensate at the network layer.

  2. Documentation is a security control. Explicitly calling out dangerous defaults in README files and deployment manifests prevents operators from unknowingly deploying insecure configurations.

  3. Upgrade paths matter. NFSv4's elimination of rpcbind dependency for the primary mount path is a meaningful security improvement — evaluate whether your use case can migrate.

  4. Least privilege applies to network exposure too. Every open port is an attack surface. Port 111 should be treated with the same caution as any other privileged service port.

Security in infrastructure components like NFS is often overlooked because these services "just work" — but that reliability can mask decades-old design decisions made when network trust models were very different. Taking the time to audit and harden these foundational services is exactly the kind of security hygiene that prevents serious breaches.


This vulnerability was automatically detected and fixed by OrbisAI Security. Automated security scanning helps catch configuration-level vulnerabilities that traditional SAST tools often miss.

Frequently Asked Questions

What is unauthenticated RPC service registration?

It's a vulnerability where rpcbind (the RPC portmapper) accepts service registration requests from any network source without verifying the requester's identity, allowing attackers to register malicious services under legitimate RPC program numbers like NFS (100003).

How do you prevent unauthenticated RPC registration in NFS deployments?

Implement network-level access controls using host-based firewalls (iptables/firewalld) or Kubernetes NetworkPolicies to restrict rpcbind port 111 access to only trusted sources, such as localhost or specific service pods within the same namespace.

What CWE is unauthenticated RPC service registration?

This vulnerability maps to CWE-306 (Missing Authentication for Critical Function), as rpcbind performs the critical function of mapping RPC services to network ports without authenticating registration requests.

Is running rpcbind on a private network enough to prevent this vulnerability?

No, private networks can still contain compromised hosts or malicious insiders. Defense-in-depth requires explicit network policies that restrict rpcbind access to only the specific pods or hosts that legitimately need to register or query RPC services.

Can static analysis detect unauthenticated RPC registration vulnerabilities?

Static analysis tools can identify exposed rpcbind configurations and missing network policies in infrastructure-as-code, but runtime network analysis and configuration auditing are more effective for detecting this deployment-level vulnerability.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #1078

Related Articles

high

How missing Dependabot cooldown happens in GitHub Actions and how to fix it

A high-severity configuration vulnerability was discovered in a `.github/dependabot.yml` file that lacked a cooldown period for package updates. Without this safeguard, Dependabot could immediately propose updates to newly published package versions—including potentially malicious or unstable releases. The fix adds a simple `cooldown` block with a 7-day waiting period before any new package version is suggested.

high

How Server-Sent Events Injection via Unsanitized Newlines happens in Node.js h3 and how to fix it

A high-severity Server-Sent Events (SSE) injection vulnerability (CVE-2026-33128) was discovered in the h3 HTTP framework, where unsanitized newline characters in event stream fields could allow attackers to inject arbitrary SSE messages. The fix upgrades h3 from version 1.15.5 to 1.15.6 in the frontend's dependency tree, ensuring that newline characters are properly sanitized before being written to event streams.

high

How buffer overflow from unsafe string copy functions happens in C network interface code and how to fix it

A high-severity buffer overflow vulnerability was discovered in `generic/eth-impl.c`, where unsafe `strncpy()` and `sprintf()` calls could write beyond buffer boundaries when handling network interface names and device filenames. The fix replaced these dangerous functions with bounded `snprintf()` calls that guarantee null-termination and prevent memory corruption.

high

How Memory Exhaustion via Large Comma-Separated Selector Lists happens in Python Soup Sieve and how to fix it

A high-severity memory exhaustion vulnerability (CVE-2026-49476) was discovered in Soup Sieve version 2.8.3, affecting Python applications that parse CSS selectors from user-controlled input. The vulnerability allows attackers to craft malicious selector lists that consume excessive memory, potentially causing denial of service. The fix involves upgrading to soupsieve 2.8.4, which implements proper resource limits on selector parsing.

high

How prototype pollution via `__proto__` key happens in Node.js defu and how to fix it

A high-severity prototype pollution vulnerability (CVE-2026-35209) was discovered in the `defu` package version 6.1.4, which allowed attackers to inject properties into JavaScript's `Object.prototype` via the `__proto__` key in defaults arguments. The fix upgrades `defu` to version 6.1.5 in the frontend's dependency tree, protecting downstream consumers like `c12` and `dotenv` configuration loaders from malicious property injection.

high

How memory exhaustion via large comma-separated selector lists happens in Python soupsieve and how to fix it

A high-severity memory exhaustion vulnerability (CVE-2026-49476) was discovered in soupsieve 2.8.3, a CSS selector library used by BeautifulSoup in Python. An attacker who could influence CSS selector input could craft large comma-separated selector lists to exhaust system memory, causing denial of service. The fix upgrades soupsieve from 2.8.3 to 2.8.4 in the backend's `uv.lock` dependency file.