Skip to main content
compliance · gcp

Firewall rules allowing port ranges instead of discrete ports

resource types
1
rule IDs covered
1
severity
medium

What does ZopNight detect here?

Firewall rules whose allowed ports include a span like 8000-9000 rather than discrete ports are flagged medium by ZopNight rule RC-1253. A range admitting 1,001 ports to serve 2 services is standing attack surface. The discoverer parses every ports entry, so detection is proven from rule config.

Signal and threshold

How ZopNight evaluates Firewall rules allowing port ranges instead of discrete ports.
Field Value
Rule IDsRC-1253
Categorycompliance
Severitymedium
Metricnone — pure configuration read
Sourcevpc_firewall_range.go

Spans reviewers cannot reason about

A firewall rule listing tcp:443 makes a reviewable claim: the web tier is reachable. A rule listing tcp:8000-9000 makes a claim nobody can check. Which of those 1,001 ports carry a real service, and which are simply open in case something binds there later? Ranges usually enter a ruleset as an estimate (“the app uses some ports around 8080”) and then fossilize, because narrowing them requires the knowledge that writing them let the team avoid gathering. Every change review after that inherits a span instead of a fact.

How lo-hi parsing decides

The discoverer walks every allowed[] entry on the rule and parses each ports[] token. A token of the form lo-hi where the two bounds differ (1000-2000) marks the rule as range-using; a single port like 22 does not, and the scan covers all entries, not just internet-facing ones, because range hygiene applies to internal rules too. The resulting marker is written in both polarities, and RC-1253 fires only on an explicit true. A rule whose port shape was never classified abstains. Provider config is the only input, read via Cloud Asset Inventory under roles/cloudasset.viewer.

Not the same finding as all-ports

A boundary worth knowing: an entry with no ports[] at all opens every port for its protocol, but that is deliberately not counted as a range here, since it belongs to the separate all-ports finding (RC-135), which is critical rather than medium. RC-1253 covers the middle ground: rules that did enumerate, but enumerated with a span. The two findings never double-report the same shape.

Surface the ranges in your rule set

Terminal window
gcloud compute firewall-rules list \
--format="table(name,network,allowed[].map().firewall_rule().list())" \
| grep -E '[0-9]+-[0-9]+'

Each hyphenated entry in the output is a span this rule would flag.

Shrinking a range safely

Replace estimation with observation: enable firewall rule logging on the ranged rule and let a representative traffic cycle accumulate, then read off the discrete ports that actually matched. Rewrite the rule to list exactly those, keep the ranged rule disabled, not deleted, for a rollback window, and remove it once nothing breaks. The finding clears automatically when the discoverer next scans the rule and finds only discrete ports.

See it fire on your bill.

Connect an account read-only. The first findings land in minutes.

417 rule families across 353 resource types on 22 platforms. Every threshold, metric, and IAM action is documented on these pages before you grant anything.

417 rule families documented
353 resource types covered
read-only default access level
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·