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.
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 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> |
| conditions | network_reachability |
| state logic | CONDITIONAL(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.