fix(gcp): detect SSH/RDP exposure when the port is not first in a multi-port firewall rule (#12137)

Co-authored-by: rayair250-droid <ray.air250@gmail.com>
Co-authored-by: Hugo P.Brito <hugopbrit@gmail.com>
This commit is contained in:
Prowler Bot
2026-07-27 16:52:02 +01:00
committed by GitHub
co-authored by rayair250-droid Hugo P.Brito
parent 9d82875037
commit 489e5dc7cf
5 changed files with 87 additions and 2 deletions
@@ -0,0 +1 @@
GCP firewall SSH and RDP checks now detect exposed target ports in any position within multi-port rules
@@ -31,7 +31,7 @@ class compute_firewall_rdp_access_from_the_internet_allowed(Check):
break
elif int(port) == 3389:
opened_port = True
break
break
if (
"0.0.0.0/0" in firewall.source_ranges
and firewall.direction == "INGRESS"
@@ -31,7 +31,7 @@ class compute_firewall_ssh_access_from_the_internet_allowed(Check):
break
elif int(port) == 22:
opened_port = True
break
break
if (
"0.0.0.0/0" in firewall.source_ranges
and firewall.direction == "INGRESS"
@@ -279,6 +279,48 @@ class Test_compute_firewall_rdp_access_from_the_internet_allowed:
)
assert result[0].resource_id == firewall.id
def test_one_non_compliant_rule_with_multiple_ports(self):
from prowler.providers.gcp.services.compute.compute_service import Firewall
firewall = Firewall(
name="test",
id="1234567890",
source_ranges=["0.0.0.0/0"],
direction="INGRESS",
allowed_rules=[{"IPProtocol": "tcp", "ports": ["80", "3389"]}],
project_id=GCP_PROJECT_ID,
)
compute_client = mock.MagicMock()
compute_client.project_ids = [GCP_PROJECT_ID]
compute_client.firewalls = [firewall]
compute_client.region = "global"
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_gcp_provider(),
),
mock.patch(
"prowler.providers.gcp.services.compute.compute_firewall_rdp_access_from_the_internet_allowed.compute_firewall_rdp_access_from_the_internet_allowed.compute_client",
new=compute_client,
),
):
from prowler.providers.gcp.services.compute.compute_firewall_rdp_access_from_the_internet_allowed.compute_firewall_rdp_access_from_the_internet_allowed import (
compute_firewall_rdp_access_from_the_internet_allowed,
)
check = compute_firewall_rdp_access_from_the_internet_allowed()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert search(
f"Firewall {firewall.name} does exposes port 3389",
result[0].status_extended,
)
assert result[0].resource_id == firewall.id
def test_one_non_compliant_rule_with_port_range(self):
from prowler.providers.gcp.services.compute.compute_service import Firewall
@@ -279,6 +279,48 @@ class Test_compute_firewall_ssh_access_from_the_internet_allowed:
)
assert result[0].resource_id == firewall.id
def test_one_non_compliant_rule_with_multiple_ports(self):
from prowler.providers.gcp.services.compute.compute_service import Firewall
firewall = Firewall(
name="test",
id="1234567890",
source_ranges=["0.0.0.0/0"],
direction="INGRESS",
allowed_rules=[{"IPProtocol": "tcp", "ports": ["80", "22"]}],
project_id=GCP_PROJECT_ID,
)
compute_client = mock.MagicMock()
compute_client.project_ids = [GCP_PROJECT_ID]
compute_client.firewalls = [firewall]
compute_client.region = "global"
with (
mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_gcp_provider(),
),
mock.patch(
"prowler.providers.gcp.services.compute.compute_firewall_ssh_access_from_the_internet_allowed.compute_firewall_ssh_access_from_the_internet_allowed.compute_client",
new=compute_client,
),
):
from prowler.providers.gcp.services.compute.compute_firewall_ssh_access_from_the_internet_allowed.compute_firewall_ssh_access_from_the_internet_allowed import (
compute_firewall_ssh_access_from_the_internet_allowed,
)
check = compute_firewall_ssh_access_from_the_internet_allowed()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert search(
f"Firewall {firewall.name} does exposes port 22",
result[0].status_extended,
)
assert result[0].resource_id == firewall.id
def test_one_non_compliant_rule_with_port_range(self):
from prowler.providers.gcp.services.compute.compute_service import Firewall