Back to Checks
alibabacloud

Security group restricts RDP access from the internet

ecs_securitygroup_restrict_rdp_internet
Service: ecsSeverity: high
OfficialBuilt-inVerified
Categories:internet-exposed
Resource Type:ALIYUN::ECS::SecurityGroup

Alibaba Cloud ECS security groups provide stateful filtering of ingress and egress network traffic to cloud resources. This check verifies that no security group allows unrestricted ingress access to port 3389 (RDP) from the internet (0.0.0.0/0 or ::/0). Restricting RDP access to trusted IP addresses significantly reduces the attack surface of ECS instances.

Prowler logoProwlerprowler-provider-alibabacloud

Risk

Unrestricted RDP access from the internet (0.0.0.0/0) exposes systems to brute force attacks, credential stuffing, and exploitation of RDP vulnerabilities such as BlueKeep. This can lead to unauthorized access, data exfiltration, and full system compromise, impacting confidentiality, integrity, and availability.

Run this check with Prowler

Run in Prowler Cloud
Run
prowler alibabacloud --checks ecs_securitygroup_restrict_rdp_internet

Recommendation

Restrict RDP (port 3389) access in security groups to only trusted IP addresses or CIDR blocks. Remove any rules allowing access from 0.0.0.0/0 or ::/0.

Remediation

CLI

aliyun ecs RevokeSecurityGroup --SecurityGroupId <security_group_id> --IpProtocol tcp --PortRange 3389/3389 --SourceCidrIp 0.0.0.0/0

Terraform

resource "alicloud_security_group_rule" "deny_rdp_internet" {
  type              = "ingress"
  ip_protocol       = "tcp"
  port_range        = "3389/3389"
  security_group_id = alicloud_security_group.example.id
  cidr_ip           = "10.0.0.0/8"  # Restrict to internal network
  policy            = "accept"
}

Other

1Log on to the **ECS Console**.
2In the left-side navigation pane, choose **Network & Security** > **Security Groups**.
3Find the target security group and click **Add Rules**.
4Locate the rule allowing port `3389` from `0.0.0.0/0`.
5Modify the Source IP range to a specific trusted IP or CIDR block.
6Click **Save**.

Check Code

from prowler.lib.check.models import Check, CheckReportAlibabaCloud
from prowler.providers.alibabacloud.services.ecs.ecs_client import ecs_client
from prowler.providers.alibabacloud.services.ecs.lib.security_groups import (
    is_public_cidr,
    port_in_range,
)


class ecs_securitygroup_restrict_rdp_internet(Check):
    """Check if security groups restrict RDP (port 3389) access from the internet."""

    def execute(self) -> list[CheckReportAlibabaCloud]:
        findings = []
        check_port = 3389  # RDP port

        for sg_arn, security_group in ecs_client.security_groups.items():
            report = CheckReportAlibabaCloud(
                metadata=self.metadata(), resource=security_group
            )
            report.region = security_group.region
            report.resource_id = security_group.id
            report.resource_arn = security_group.arn

            # Check ingress rules for unrestricted access to RDP port
            has_unrestricted_access = False

            for ingress_rule in security_group.ingress_rules:
                # Check if rule allows traffic (policy == "accept")
                if str(ingress_rule.get("policy", "accept")).lower() != "accept":
                    continue

                # Check protocol (tcp for RDP)
                protocol = ingress_rule.get("ip_protocol", "").lower()
                if protocol not in ["tcp", "all"]:
                    continue

                # Check if source is public (0.0.0.0/0)
                source_cidr = ingress_rule.get("source_cidr_ip", "")
                if not is_public_cidr(source_cidr):
                    continue

                # Check if port range includes RDP port
                port_range = ingress_rule.get("port_range", "")

                if protocol == "all":
                    # If protocol is "all", all ports are open
                    has_unrestricted_access = True
                    break
                elif port_in_range(port_range, check_port):
                    has_unrestricted_access = True
                    break

            if has_unrestricted_access:
                report.status = "FAIL"
                report.status_extended = (
                    f"Security group {security_group.name} ({security_group.id}) "
                    f"has Microsoft RDP port 3389 open to the internet (0.0.0.0/0)."
                )
            else:
                report.status = "PASS"
                report.status_extended = (
                    f"Security group {security_group.name} ({security_group.id}) "
                    f"does not have Microsoft RDP port 3389 open to the internet."
                )

            findings.append(report)

        return findings