# GCP Firewall Rule Allows Internet Access to Sensitive Port

> Firewall rules admitting 0.0.0.0/0 to any of 11 sensitive ports (SSH 22, RDP 3389, WinRM 5985/5986, MySQL 3306, PostgreSQL 5432, MSSQL 1433, MongoDB 27017, Redis 6379, Telnet 23, FTP 21) are flagged critical by RC-134. Internet scanners find such openings within minutes of creation.

Source: https://zop.dev/integrations/gcp/recommendations/gcp-firewall-rule-allows-internet-access-to-sensitive-port
Updated: 2026-08-19

---

## Eleven ports scanners try first

ZopNight's discoverer classifies a specific port list as sensitive: the remote-management
set of SSH 22, RDP 3389, WinRM 5985 and 5986; the datastore set of MySQL 3306, PostgreSQL
5432, MSSQL 1433, MongoDB 27017 and Redis 6379; and the legacy-cleartext pair, Telnet 23 and
FTP 21. These are the ports where reachability alone is most of the compromise: management
ports invite brute-force against real login surfaces, datastore ports frequently front
services deployed with weak or default authentication, and the cleartext protocols leak
credentials to any on-path observer by design.

## Minutes from creation to first probe

Exposure here is not theoretical drift. The internet is continuously enumerated.
Services like Shodan and the botnets running their own scans typically touch a newly
opened port within minutes, and an SSH daemon on a public IP collects automated login
attempts more or less immediately and indefinitely. A rule like this created "just for
today's debugging" is being actively tested against long before it is remembered and
removed.

## Both flags must agree before RC-134 fires

The discoverer derives two markers from each firewall rule's `allowed[]`,
`sourceRanges[]`, `direction`, and `disabled` fields: one saying the rule is an enabled
ingress allow from `0.0.0.0/0` or `::/0`, one saying a sensitive port is among what it
admits. RC-134 fires only when both read explicitly true, and abstains when either is
absent. An internal-only rule on port 22, or an internet-facing rule on port 443 alone,
never fires. Detection is proven from provider config, read via Cloud Asset Inventory
under `roles/cloudasset.viewer`, and the finding is informational only.

## Ranges count too

A rule does not need to name a sensitive port to expose one. The classifier expands every
`ports[]` token, so a span like `1000-4000` is flagged because 3306 sits inside it, and a
`tcp` entry with no ports at all, meaning every port, is sensitive by inclusion. Reviewing
rules by eye misses these; the enumeration does not.

## Find the exposures in your project

```bash
gcloud compute firewall-rules list \
  --filter="direction=INGRESS AND disabled=false AND sourceRanges.list():0.0.0.0/0" \
  --format="table(name,network,allowed[].map().firewall_rule().list())"
```

Check the output for the eleven ports above, or ranges containing them.

## IAP and Auth Proxy instead of open ports

The durable fix removes the need for the opening rather than narrowing it.
Identity-Aware Proxy tunnels SSH and RDP through Google's front end with per-identity
authorization, leaving no listening port on the instance's public address. Databases
belong behind Cloud SQL Auth Proxy or private IP with VPC peering. Where a direct rule
must survive, shrink its source to named, owned CIDRs such as an office range or VPN egress,
and treat any remaining `0.0.0.0/0` entry as an incident, not a configuration.
