gcp-vpc-firewall-internet-exposure

An ingress firewall rule allowing 0.0.0.0/0 (or ::/0) on a specific port permits any internet host to initiate a connection to matching VMs on that port.

derived gcp emits CanReachPort

match (record)

{ "field": "sourceRanges", "resource_type": "compute.googleapis.com/Firewall" }

where

firewall.direction == INGRESS firewall.sourceRanges contains '0.0.0.0/0' or '::/0' firewall.action == allow (i.e. no 'denied' array; rule is in the 'allowed' list) firewall.disabled != true port determined from firewall.allowed[].ports (specific port(s) or all)

emit

source typeFirewall
target typeCompute
source<Firewall node for this rule (represents the network-level allow condition)>
target<VMs in firewall.network matching firewall.targetTags or firewall.targetServiceAccounts; ALL VMs in the network when neither is set>
conditionsnetwork_reachability
state logicCONDITIONAL(network_reachability) — the firewall rule is a necessary but not sufficient condition; a route to the internet gateway must also exist (default for auto-mode VPCs). ACTIVE when the network has a default route via default-internet-gateway and the VM has an external IP or sits behind an external LB.

Narrative

Firewall rule {firewall.name} in VPC {network.name} allows inbound connections from the entire internet (0.0.0.0/0) on port {port} to {target_description}. An internet adversary can initiate a TCP/UDP session to any matching VM on this port.

Raw rule rules/derived/gcp/vpc.yaml

id: gcp-vpc-firewall-internet-exposure
emits: CanReachPort
description: An ingress firewall rule allowing 0.0.0.0/0 (or ::/0) on a specific port permits any internet
  host to initiate a connection to matching VMs on that port.
applies_to:
- gcp
match_record:
  resource_type: compute.googleapis.com/Firewall
  field: sourceRanges
where:
- firewall.direction == INGRESS
- firewall.sourceRanges contains '0.0.0.0/0' or '::/0'
- firewall.action == allow (i.e. no 'denied' array; rule is in the 'allowed' list)
- firewall.disabled != true
- port determined from firewall.allowed[].ports (specific port(s) or all)
emit:
  source_type: Firewall
  target_type: Compute
  source: <Firewall node for this rule (represents the network-level allow condition)>
  target: <VMs in firewall.network matching firewall.targetTags or firewall.targetServiceAccounts; ALL
    VMs in the network when neither is set>
  permissions: []
  conditions:
  - network_reachability
  state_logic: "CONDITIONAL(network_reachability) \u2014 the firewall rule is a necessary but not sufficient\
    \ condition; a route to the internet gateway must also exist (default for auto-mode VPCs). ACTIVE\
    \ when the network has a default route via default-internet-gateway and the VM has an external IP\
    \ or sits behind an external LB."
  confidence: '0.85'
  derived_from:
  - '<Firewall record: direction=INGRESS, sourceRanges include 0.0.0.0/0>'
  false_positive_note: "(1) targetTags / targetServiceAccounts narrow applicability \u2014 a rule is NOT\
    \ open to all VMs unless both fields are empty. Evaluate the target filter strictly; do NOT emit against\
    \ VMs whose tags/SA do not match. (2) A higher-priority hierarchical firewall policy DENY at org/folder\
    \ scope overrides this VPC-level allow \u2014 emit as BLOCKED if a hierarchical deny is present on\
    \ the same port/direction at a higher priority. (3) GCP firewall rules are stateful; inbound allow\
    \ implies return traffic allowed. Do NOT model egress separately from this fact. (4) A VM with only\
    \ an internal IP and no external IP or external LB cannot be reached from 0.0.0.0/0 even if this firewall\
    \ rule exists \u2014 downgrade to CONDITIONAL(network_reachability) in that case. (5) MISSING: IAP\
    \ bypass escalation path \u2014 when IAP TCP forwarding is the only authorized ingress and an attacker\
    \ with compute.firewalls.create adds a direct allow on the same port from 0.0.0.0/0, they bypass IAP\
    \ entirely. This distinct high-value path should be covered by a separate rule or escalation derivation\
    \ (needs additional rule in explicit/gcp-vpc.yaml)."
  narrative: Firewall rule {firewall.name} in VPC {network.name} allows inbound connections from the entire
    internet (0.0.0.0/0) on port {port} to {target_description}. An internet adversary can initiate a
    TCP/UDP session to any matching VM on this port.
move · open · esc close