Lateral credential harvesting via process namespace sharing

Lateral credential harvesting via process namespace sharing

●1 ●7 ●36
calendar_today • schedule1 min read

Github Source:
https://github.com/ndouglas-edera/hostpid-risk/tree/main

In a multi-tenant or shared Kubernetes node environment, containers are supposed to be isolated environments. However, this demo proves that if a malicious or compromised pod is deployed with host-level privileges, it can spy on neighbouring workloads running on the same node without needing a software vulnerability or zero-day exploit.

Example script

You can download the automation script from Github:

wget https://raw.githubusercontent.com/ndouglas-edera/hostpid-risk/refs/heads/main/hostpid-risk.sh
chmod +x hostpid-risk.sh

If you have a Kubernetes cluster already running (like on Docker Desktop or kind), you can run the below script:

./hostpid-risk.sh

What is the security misconfiguration exactly?

The exploit relies on 2 specific fields in the inspector-pod YAML manifest working together:

spec:
  hostPID: true            # <--- Misconfiguration #1: Breaks PID isolation
  containers:
  - name: inspector
    securityContext:
      privileged: true     # <--- Misconfiguration #2: Overrides Linux permissions

How it works technically

  1. Normally, Linux container runtimes place each pod in their own isolated Process ID (PID) namespace.
    Setting hostPID: true actually forces the pod to share the host node’s global PID namespace.
  2. Suddenly, ps -ef inside the container displays every process running on the underlying node.
    This includes processes belonging to other pods (target-app).
  3. This would bypass Linux kernel profiles like AppArmor and SELinux - granting full capabilities (like CAP_SYS_ADMIN).
  4. In Linux, the virtual /proc filesystem exposes process metadata. The file /proc/<PID>/environ holds the environment variables loaded into memory when that process was spawned.
  5. Because inspector-pod has host-level permissions, it can read /proc/30629/environ belonging to target-app before extracting the DB_PASSWORD=SuperSecretPassword123! creds.

Strategy 1 - PSS in Kubernetes

Pod Security Standards (or PSS, for short) is a built-in policy Kubernetes framework managed by the Pod Security Admission (PSA) controller. It categorises security into 3 levels:

  • Privileged: Unrestricted (Allowing hostPID: true & privileged: true)
  • Baseline: Prevents known privilege escalations (Blocking hostPID: true, host paths, and host networking)
  • Restricted: Hardened best practices (Requires dropping capabilities, non-root users, and more..)

So, how do PSS policies block the attack?
By either applying a Baseline or Restricted policy to the target namespace, Kubernetes will reject inspector-pod at the API server before it can ever be scheduled. Here's an example of enforcing the baseline profile on the default namespace

kubectl label --overwrite ns default pod-security.kubernetes.io/enforce=baseline

If an attacker tries to apply inspector-pod.yaml now, the Kubernetes API server responds with an immediate error, similar to other admission control technologies like OPA:

Error from server (Forbidden): pods "inspector-pod" is forbidden: 
violates PodSecurity "baseline:latest": hostPID (spec.hostPID=true), 
privileged (container "inspector" must not set securityContext.privileged=true)

Strategy 2 - Runtime Isolation

While PSS works at the API controlplane-level (by stopping bad YAML from being accepted), the ideal runtime isolation approach should be applied at the Kernel-level.

For context, hostPID: true and privileged: true are commonly enabled purely by accident, oftentimes by developers while troubleshooting nodes, and through legacy Helm charts, or by third-party monitoring and observability agents (like eBPF probes, custom log forwarders, or node-exporters) that require node visibility. And when this happens in a multi-tenant cluster (that's shared across departments or clients), compromising a single pod with host privileges instantly compromises all secrets across all pods on that same node, rendering the entire namespace-level isolation useless.

So, what if an attacker has cluster-admin privileges or bypasses PSS?
Standard Kubernetes containers share a single, common Linux kernel. If namespace boundaries break, everything on that kernel is exposed. In the case of Edera Zones (and microVM-based runtimes like Kata Containers or gVisor, more generally) they implement a defence-in-depth strategy by isolating all your workloads into distinct hypervisor boundaries or independent kernel spaces.

Under gVisor, Kata Containers, or Edera Zones, even if a pod sets hostPID: true and privileged: true, hostPID only shares the PID namespace of the isolated guest kernel / microVM sandbox, not the underlying bare-metal host node. The malicious pod sees only itself and its sandbox. In this way, it can't see processes from neighbouring pods running in parallel sandboxes.

Note: I will continue to update the Github repository to better improve these security automation demos.

🔥 Join developers growing publicly
Share your knowledge, build in public, and grow your developer presence with a global community.

More Posts

The Death of Smart Contract Audits: Why NexusVeritas Hunts Web3 Scammers via Behavioral DNA

VeritasLab - Jun 12

Comparison: Universal Import vs. Plaid/Yodlee

Pocket Portfolio - Mar 12

Kamal vs Kubernetes: An Honest Comparison for Teams Who Don’t Need 1,000 Services

Alexandre Vazquez - Jul 24

MCP Is the USB-C of AI. So Why Are You Plugging Everything In?

Ken W. Algerverified - Jun 10

HYCU's Free aiR Graph Maps Every Agent in Entra ID and Okta, Then Asks If You Can Recover

Tom Smithverified - Oct 8
chevron_left
1.5k Points • 44 Badges
16Posts
10Comments
15Connections
Head of Developer Relations at Edera. Working on projects related to Kubernetes, the Linux kernel, and secure software development,.

Related Jobs

View all jobs →

Commenters (This Week)

4 comments
1 comment

Contribute meaningful comments to climb the leaderboard and earn badges!