Goal
Model lateral-movement gaps in pod networking as first-class findings: a flat pod network where any compromised pod can reach every other pod is one of the most impactful real-world post-RCE primitives, and kuberoast doesn't currently surface it.
This is the next offensive surface to cover after v0.4.0 / control-plane probes.
What "world class" looks like
LATERAL-FLAT-NAMESPACE (high)
Namespace has pods but no NetworkPolicy selects them → flat L3/L4 reach to everything in the namespace.
- Impact: any pod RCE → reach every other pod in the namespace (databases, caches, internal admin APIs).
- PoC:
kubectl run rce-test --rm -it --image=nicolaka/netshoot -n <ns> -- nmap -p- <other-pod-ip>
- Remediation: apply a default-deny ingress NetworkPolicy, then add explicit allows.
LATERAL-NO-DEFAULT-DENY (medium)
Namespace has some NetworkPolicies, but no default-deny (no policy selects all pods with empty ingress). Pods not matched by any policy stay open → asymmetric, easy to miss.
LATERAL-WIDE-ALLOW (medium)
A NetworkPolicy ingress rule with from: [] (allow from anywhere) or ipBlock: 0.0.0.0/0 not restricted to a tight CIDR → policy is theatrical, not gating.
LATERAL-EGRESS-OPEN (medium)
No egress policies in the namespace → C2 / data exfil unconstrained. Already partially handled in cloud.py (IMDS-specific), but this is the broader case.
LATERAL-CROSS-NS (high)
NetworkPolicy ingress allows from another namespace's pods via namespaceSelector with broad match labels ({} or matching every ns) → cross-tenant lateral movement.
Cross-walks to existing findings
- Tier-0 + flat-network: a tier-0 SA in a flat namespace is much worse — bump the chain's framing.
- Cloud-IMDS: redundant with
LATERAL-EGRESS-OPEN for the metadata IP; keep both, dedupe in the report.
Implementation sketch
- New scanner:
kuberoast/scanners/netpol.py
- Inputs already plumbed:
list_all_network_policies (added in v0.4.0), pods, namespaces.
- Skip system namespaces (
kube-system, kube-public, kube-node-lease) by default — they're expected flat.
- Tests: ~10 covering each of the 5 findings + the cross-walk cases.
Out of scope (separate issues)
- CNI-specific extensions (Cilium NetworkPolicy CRDs, Calico GlobalNetworkPolicy)
- Service mesh authorization policies (Istio, Linkerd) — different model
- L7 / HTTP-aware policies
References
cc: tracked from PR #5 discussion, mentioned in README.md#Roadmap.
Goal
Model lateral-movement gaps in pod networking as first-class findings: a flat pod network where any compromised pod can reach every other pod is one of the most impactful real-world post-RCE primitives, and
kuberoastdoesn't currently surface it.This is the next offensive surface to cover after v0.4.0 / control-plane probes.
What "world class" looks like
LATERAL-FLAT-NAMESPACE(high)Namespace has pods but no NetworkPolicy selects them → flat L3/L4 reach to everything in the namespace.
kubectl run rce-test --rm -it --image=nicolaka/netshoot -n <ns> -- nmap -p- <other-pod-ip>LATERAL-NO-DEFAULT-DENY(medium)Namespace has some NetworkPolicies, but no default-deny (no policy selects all pods with empty ingress). Pods not matched by any policy stay open → asymmetric, easy to miss.
LATERAL-WIDE-ALLOW(medium)A NetworkPolicy ingress rule with
from: [](allow from anywhere) oripBlock: 0.0.0.0/0not restricted to a tight CIDR → policy is theatrical, not gating.LATERAL-EGRESS-OPEN(medium)No egress policies in the namespace → C2 / data exfil unconstrained. Already partially handled in
cloud.py(IMDS-specific), but this is the broader case.LATERAL-CROSS-NS(high)NetworkPolicy ingress allows from another namespace's pods via
namespaceSelectorwith broad match labels ({}or matching every ns) → cross-tenant lateral movement.Cross-walks to existing findings
LATERAL-EGRESS-OPENfor the metadata IP; keep both, dedupe in the report.Implementation sketch
kuberoast/scanners/netpol.pylist_all_network_policies(added in v0.4.0), pods, namespaces.kube-system,kube-public,kube-node-lease) by default — they're expected flat.Out of scope (separate issues)
References
cc: tracked from PR #5 discussion, mentioned in
README.md#Roadmap.