A NetworkPolicy is an allowlist of permitted traffic for the pods it selects, enforced by the CNI. Its weaknesses are structural rather than exploit-based. A policy applies only to the pods its selector matches, so pods and whole namespaces with no policy are unrestricted. Policies frequently define ingress but omit egress, or vice versa. They commonly leave DNS and the API server reachable because workloads need them. And rules scoped to pod traffic do not constrain node-level or host-network paths. Mapping these gaps is how an attacker reaches a target the policy was supposed to isolate.
Find the gaps:
# which namespaces and pods have no policy at all?
kubectl get networkpolicies -A
kubectl get ns -o name | while read ns; do \
n=$(kubectl get netpol -n ${ns#namespace/} --no-headers 2>/dev/null | wc -l); \
echo "${ns#namespace/}: $n policies"; done
# does a given policy cover egress, or only ingress?
kubectl get netpol -n <ns> -o yaml | grep -E 'policyTypes|Ingress|Egress'
Routes around a policy#
# 1. a namespace or pod with no policy is fully reachable; pivot through it
# 2. egress not restricted: exfiltrate and reach external or other-namespace targets
# 3. DNS left open: tunnel over DNS, or use allowed resolver paths
# 4. host-network path: a hostNetwork pod is on the node stack, outside pod-scoped rules
# (see Host namespaces) so it reaches node-local and policy-exempt destinations
# 5. the CNI may not enforce policy on certain traffic (e.g. node->pod, or hairpin)
Exploitation notes#
- The first check is coverage: any namespace with zero policies is open, and clusters commonly protect a few sensitive namespaces while leaving the rest flat, so a neighbour namespace is often an unrestricted pivot.
- Egress omissions are the most common functional gap; a policy that only filters ingress still lets a compromised pod reach everything outward, including other-namespace services by IP.
- A
hostNetworkpod escapes pod-scoped policy entirely because its traffic originates from the node; combine with Host namespaces. - Policy enforcement depends on the CNI actually implementing NetworkPolicy; some configurations accept the objects but do not enforce them, which
kubectl get netpolcannot reveal, so test reachability directly.