AWS Network ACL Restricts Insecure Protocols


Description

This policy validates that Network ACLs block the usage of ports typically associated with insecure or unencrypted protocols.

Query · python

# This is a list of default ports for insecure protocols. As AWS Network ACLs and Security Groups
# are not application layer aware, this is the closest approximation that can be made to blocking
# insecure protocols. Application layer firewalls can provide stronger protections.
INSECURE_PORTS = {
    21,  # FTP command channel
    25,  # Unencrypted pop3 outgoing
    23,  # Telnet
    80,  # HTTP
    110,  # Unencrypted pop3 incoming
    587,  # Unencrypted pop3 outgoing
}


def policy(resource):

    for entry in resource["Entries"]:
        # Look for ingress rules from any IP.
        # This could be modified in the future to inspect the size
        # of the source network with the ipaddress.ip_network.num_addresses call.
        if entry["Egress"]:
            continue

        # This indicates that all protocols are allowed, and the port range is ignored
        if entry["Protocol"] == "-1" or not entry["PortRange"]:
            return False

        if any(
            entry["PortRange"]["From"] <= port <= entry["PortRange"]["To"]
            for port in INSECURE_PORTS
        ):
            return False
    return True

Analyst notes

Add Network ACL entries to block ports typically associated with insecure protocols.

Raw source AWS Network ACL Restricts Insecure Protocols · Panther Python
Esc
Published by panther-labs/panther-analysis ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
AnalysisType: policy
Filename: aws_network_acl_restricts_insecure_protocols.py
PolicyID: "AWS.NetworkACL.RestrictsInsecureProtocols"
DisplayName: "AWS Network ACL Restricts Insecure Protocols"
Enabled: false
ResourceTypes:
  - AWS.EC2.NetworkACL
Tags:
  - AWS
  - PCI
  - Command and Control:Non-Application Layer Protocol
Reports:
  PCI:
    - 8.2.1
  MITRE ATT&CK:
    - TA0011:T1095
Severity: Low
Description: >
  This policy validates that Network ACLs block the usage of ports typically associated with insecure or unencrypted protocols.
Runbook: Add Network ACL entries to block ports typically associated with insecure protocols.
Reference: https://docs.aws.amazon.com/vpc/latest/userguide/vpc-recommended-nacl-rules.html
Tests:
  - Name: Network ACL Restricts Insecure Protocols
    ExpectedResult: true
    Resource:
      {
        "AccountId": "123456789012",
        "Region": "ap-southeast-2",
        "ARN": "arn:aws:ec2:ap-southeast-2:123456789012:network-acl/acl-111222333",
        "ID": "acl-111222333",
        "Tags": { "environment": "pci" },
        "ResourceID": "arn:aws:ec2:ap-southeast-2:123456789012:network-acl/acl-111222333",
        "ResourceType": "AWS.EC2.NetworkACL",
        "TimeCreated": null,
        "Associations":
          [
            {
              "NetworkAclAssociationId": "aclassoc-111222333",
              "NetworkAclId": "acl-111222333",
              "SubnetId": "subnet-111222333",
            },
          ],
        "Entries":
          [
            {
              "CidrBlock": "8.8.8.8/32",
              "Egress": false,
              "IcmpTypeCode": null,
              "Ipv6CidrBlock": null,
              "PortRange": { "From": 22, "To": 22 },
              "Protocol": "6",
              "RuleAction": "allow",
              "RuleNumber": 100,
            },
            {
              "CidrBlock": "0.0.0.0/0",
              "Egress": true,
              "IcmpTypeCode": null,
              "Ipv6CidrBlock": null,
              "PortRange": { "From": 22, "To": 22 },
              "Protocol": "6",
              "RuleAction": "allow",
              "RuleNumber": 100,
            },
          ],
        "IsDefault": true,
        "NetworkAclId": "acl-111222333",
        "OwnerId": "123456789012",
        "VpcId": "vpc-6aa60b12",
      }
  - Name: Insecure Ports Not Restricted
    ExpectedResult: false
    Resource:
      {
        "AccountId": "123456789012",
        "Region": "ap-southeast-2",
        "ARN": "arn:aws:ec2:ap-southeast-2:123456789012:network-acl/acl-111222333",
        "ID": "acl-111222333",
        "Tags": { "environment": "pci" },
        "ResourceID": "arn:aws:ec2:ap-southeast-2:123456789012:network-acl/acl-111222333",
        "ResourceType": "AWS.EC2.NetworkACL",
        "TimeCreated": null,
        "Associations":
          [
            {
              "NetworkAclAssociationId": "aclassoc-111222333",
              "NetworkAclId": "acl-111222333",
              "SubnetId": "subnet-111222333",
            },
          ],
        "Entries":
          [
            {
              "CidrBlock": "0.0.0.0/0",
              "Egress": false,
              "IcmpTypeCode": null,
              "Ipv6CidrBlock": null,
              "PortRange": { "From": 21, "To": 21 },
              "Protocol": "-1",
              "RuleAction": "allow",
              "RuleNumber": 100,
            },
          ],
        "IsDefault": true,
        "NetworkAclId": "acl-111222333",
        "OwnerId": "123456789012",
        "VpcId": "vpc-6aa60b12",
      }
  - Name: All Ports Allowed
    ExpectedResult: false
    Resource:
      {
        "OwnerId": "123456789012",
        "Region": "us-west-2",
        "Associations":
          [
            {
              "NetworkAclId": "acl-1",
              "NetworkAclAssociationId": "aclassoc-1",
              "SubnetId": "subnet-1",
            },
          ],
        "Id": "acl-1",
        "Entries":
          [
            {
              "CidrBlock": "0.0.0.0/0",
              "Egress": false,
              "RuleNumber": 100,
              "Ipv6CidrBlock": null,
              "Protocol": "-1",
              "PortRange": null,
              "IcmpTypeCode": null,
              "RuleAction": "allow",
            },
            {
              "RuleNumber": 32767,
              "Ipv6CidrBlock": null,
              "Protocol": "-1",
              "PortRange": null,
              "IcmpTypeCode": null,
              "RuleAction": "deny",
              "CidrBlock": "0.0.0.0/0",
              "Egress": false,
            },
          ],
        "VpcId": "vpc-1",
        "IsDefault": true,
        "Tags": { "environment": "pci" },
        "AccountId": "123456789012",
        "ResourceType": "AWS.EC2.NetworkACL",
        "ResourceId": "arn:aws:ec2:us-west-2:123456789012:network-acl/acl-1",
        "Arn": "arn:aws:ec2:us-west-2:123456789012:network-acl/acl-1",
        "TimeCreated": null,
      }


# ------ paired body: aws_network_acl_restricts_insecure_protocols.py ------

# This is a list of default ports for insecure protocols. As AWS Network ACLs and Security Groups
# are not application layer aware, this is the closest approximation that can be made to blocking
# insecure protocols. Application layer firewalls can provide stronger protections.
INSECURE_PORTS = {
    21,  # FTP command channel
    25,  # Unencrypted pop3 outgoing
    23,  # Telnet
    80,  # HTTP
    110,  # Unencrypted pop3 incoming
    587,  # Unencrypted pop3 outgoing
}


def policy(resource):

    for entry in resource["Entries"]:
        # Look for ingress rules from any IP.
        # This could be modified in the future to inspect the size
        # of the source network with the ipaddress.ip_network.num_addresses call.
        if entry["Egress"]:
            continue

        # This indicates that all protocols are allowed, and the port range is ignored
        if entry["Protocol"] == "-1" or not entry["PortRange"]:
            return False

        if any(
            entry["PortRange"]["From"] <= port <= entry["PortRange"]["To"]
            for port in INSECURE_PORTS
        ):
            return False
    return True

Detection rules belong to the projects that publish them and remain under their own licenses. This site indexes and links to them; it claims no rights in them.