CME-208

Outbound Network Egress Restriction (SSRF Blast Radius Containment)

Description

Network-layer egress filtering that confines application workloads to only the external destinations they require, blocking outbound connections to internal networks, cloud metadata services, and localhost. Implemented via host-based firewall rules (firewalld/nftables), Kubernetes NetworkPolicy egress rules, or cloud security group outbound rules. Complements application-level SSRF prevention (CME-1304) by providing defense-in-depth: even if the application's URL validation is bypassed through DNS rebinding, IPv6-mapped addresses, URL parser differentials, or HTTP redirect chains, the network layer blocks the resulting connection to internal resources. Specifically blocks egress to 169.254.0.0/16 (link-local/cloud metadata), 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 (RFC1918), and fd00::/8 (ULA IPv6) from application workloads that should only communicate externally.

CVSS Vector Impacts

Metric Transition Rationale
Confidentiality (C) H → L Network egress rules block the SSRF payload from reaching internal services, cloud metadata, or localhost regardless of application-layer bypass techniques; exfiltration of internal data is prevented at the transport layer
Scope (S) C → U SSRF can no longer pivot to affect internal services beyond the vulnerable component; scope change from the application to the internal network is blocked by network-layer isolation

CWE Relationships

Verification

Verify that application workloads cannot initiate outbound connections to RFC1918 ranges, link-local addresses, or localhost

$ nft list ruleset | grep -A5 'chain output' | grep -E '10\.0\.0\.0|172\.16\.0\.0|192\.168\.0\.0|169\.254'
# Expected: Drop/reject rules for RFC1918 and link-local ranges in the output chain
Platform: linux
$ kubectl get networkpolicy -n <namespace> -o jsonpath='{.items[*].spec.egress}'
# Expected: Egress rules present that restrict destination CIDRs to required external endpoints only
Platform: any
$ curl -s --connect-timeout 3 http://169.254.169.254/latest/meta-data/ -o /dev/null -w '%{http_code}' 2>&1 || echo 'blocked'
# Expected: Connection refused, timed out, or blocked — cloud metadata endpoint unreachable from application workload
Platform: any
$ Get-NetFirewallRule -Direction Outbound | Where-Object { $_.Action -eq 'Block' } | Get-NetFirewallAddressFilter | Where-Object { $_.RemoteAddress -match '10\.|172\.16|192\.168|169\.254' }
# Expected: Outbound block rules present for RFC1918 and link-local ranges
Platform: windows

Remediation

linux nftables egress rules blocking RFC1918, link-local, and cloud metadata

printf '#!/usr/sbin/nft -f\ntable inet egress_restrict {\n  chain output {\n    type filter hook output priority 0; policy accept;\n    ip daddr 169.254.0.0/16 drop\n    ip daddr 10.0.0.0/8 drop\n    ip daddr 172.16.0.0/12 drop\n    ip daddr 192.168.0.0/16 drop\n    ip daddr 127.0.0.0/8 drop\n    ip6 daddr fd00::/8 drop\n    ip6 daddr ::1 drop\n  }\n}\n' > /etc/nftables/cme-208-egress.nft
grep -q 'cme-208-egress.nft' /etc/sysconfig/nftables.conf 2>/dev/null || echo 'include "/etc/nftables/cme-208-egress.nft"' >> /etc/sysconfig/nftables.conf
nft -f /etc/nftables/cme-208-egress.nft
kubernetes Kubernetes NetworkPolicy restricting egress to allowed external CIDRs only

kubectl apply -n <namespace> -f - <<'EOF'
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: cme-208-default-deny-egress
spec:
  podSelector: {}
  policyTypes:
  - Egress
EOF
kubectl apply -n <namespace> -f - <<'EOF'
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: cme-208-allow-dns
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - ports:
    - protocol: UDP
      port: 53
    - protocol: TCP
      port: 53
EOF
kubectl apply -n <namespace> -f - <<'EOF'
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: cme-208-allow-external
spec:
  podSelector:
    matchLabels:
      app: <app_label>
  policyTypes:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: <allowed_cidr>
        except:
        - 10.0.0.0/8
        - 172.16.0.0/12
        - 192.168.0.0/16
        - 169.254.0.0/16
EOF
windows Windows Firewall outbound block rules for RFC1918 and cloud metadata ranges

New-NetFirewallRule -DisplayName 'CME-208 Block Egress RFC1918 10/8' -Direction Outbound -Action Block -RemoteAddress 10.0.0.0/8 -Protocol Any
New-NetFirewallRule -DisplayName 'CME-208 Block Egress RFC1918 172.16/12' -Direction Outbound -Action Block -RemoteAddress 172.16.0.0/12 -Protocol Any
New-NetFirewallRule -DisplayName 'CME-208 Block Egress RFC1918 192.168/16' -Direction Outbound -Action Block -RemoteAddress 192.168.0.0/16 -Protocol Any
New-NetFirewallRule -DisplayName 'CME-208 Block Egress Link-Local/Metadata' -Direction Outbound -Action Block -RemoteAddress 169.254.0.0/16 -Protocol Any
← CME-207: DNS Rebinding Protection CME-209: Kubernetes NetworkPolicy Enforcement →