AWS ELB SSL Policies


Description

Ensures that deprecated TLS versions are not supported in internet-facing load balancers

Query · python

# https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html#describe-ssl-policies
# Requirements to be "safe": 1) TLSv1.2+ only; 2) Forward Secrecy

TLS_SAFE_POLICIES = {
    "ELBSecurityPolicy-FS-1-2-2019-08",
    "ELBSecurityPolicy-FS-1-2-Res-2019-08",
    "ELBSecurityPolicy-FS-1-2-Res-2020-10",
    "ELBSecurityPolicy-TLS13-1-2-2021-06",
    "ELBSecurityPolicy-TLS13-1-2-Res-2021-06",
    "ELBSecurityPolicy-TLS13-1-3-2021-06",
}


def policy(resource):
    # Ignore load balancers that aren't serving internet traffic
    if resource.get("Scheme") == "internal":
        return True

    return len(resource.get("Listeners") if resource.get("Listeners") else []) >= 1 and all(
        (each_policy in TLS_SAFE_POLICIES for each_policy in resource.get("SSLPolicies", {}).keys())
    )

Analyst notes

Update your load balancer's SSLPolicies to only support modern TLS versions

Raw source AWS ELB SSL Policies · Panther Python
Esc
Published by panther-labs/panther-analysis ↗, licensed under Apache 2.0 ↗. Reproduced here unmodified.
AnalysisType: policy
Filename: aws_alb_ssl_policy.py
PolicyID: "AWS.ELBv2.SSLPolicy"
DisplayName: "AWS ELB SSL Policies"
Enabled: true
ResourceTypes:
  - AWS.ELBV2.ApplicationLoadBalancer
Tags:
  - AWS
  - Panther
  - Initial Access:Exploit Public-Facing Application
Reports:
  PCI:
    - 2.2.3
    - 4.1
  MITRE ATT&CK:
    - TA0001:T1190
Severity: Medium
Description: Ensures that deprecated TLS versions are not supported in internet-facing load balancers
Runbook: >
  Update your load balancer's SSLPolicies to only support modern TLS versions
Reference: https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html
Tests:
  - Name: Strong Ciphers Internet Facing
    ExpectedResult: true
    Resource:
      {
        "IpAddressType": "ipv4",
        "Type": "application",
        "Tags": { "Application": "Test" },
        "AvailabilityZones":
          [
            {
              "LoadBalancerAddresses": null,
              "ZoneName": "us-east-1b",
              "SubnetId": "subnet-05f7b81cc5d97e0e2",
            },
            {
              "ZoneName": "us-east-1a",
              "SubnetId": "subnet-07419606a40f4c414",
              "LoadBalancerAddresses": null,
            },
          ],
        "AccountId": "123456789012",
        "DNSName": "web-360787852.us-east-1.elb.amazonaws.com",
        "Listeners":
          [
            {
              "DefaultActions":
                [
                  {
                    "RedirectConfig": null,
                    "ForwardConfig":
                      {
                        "TargetGroups":
                          [
                            {
                              "TargetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/web/54eedfcacc3949ef",
                              "Weight": 1,
                            },
                          ],
                        "TargetGroupStickinessConfig":
                          { "Enabled": false, "DurationSeconds": null },
                      },
                    "AuthenticateOidcConfig": null,
                    "Order": null,
                    "TargetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/web/54eedfcacc3949ef",
                    "FixedResponseConfig": null,
                    "AuthenticateCognitoConfig": null,
                    "Type": "forward",
                  },
                ],
              "Port": 443,
              "Certificates":
                [
                  {
                    "IsDefault": null,
                    "CertificateArn": "arn:aws:acm:us-east-1:123456789012:certificate/10c4e713-9bb5-4ccf-aabc-1c9119370038",
                  },
                ],
              "Protocol": "HTTPS",
              "ListenerArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:listener/app/web/3ff2fab33a993e0c/995359b182328b77",
              "SslPolicy": "ELBSecurityPolicy-2016-08",
              "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/web/3ff2fab33a993e0c",
            },
          ],
        "ResourceId": "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/web/3ff2fab33a993e0c",
        "Scheme": "internet-facing",
        "VpcId": "vpc-0aa6688dd88484847",
        "State": { "Code": "active", "Reason": null },
        "Name": "web",
        "SSLPolicies":
          {
            "ELBSecurityPolicy-FS-1-2-2019-08":
              {
                "SslProtocols": ["TLSv1.2"],
                "Ciphers":
                  [
                    { "Name": "ECDHE-ECDSA-AES128-GCM-SHA256", "Priority": 1 },
                    { "Name": "ECDHE-RSA-AES128-GCM-SHA256", "Priority": 2 },
                    { "Name": "ECDHE-ECDSA-AES128-SHA256", "Priority": 3 },
                    { "Name": "ECDHE-RSA-AES128-SHA256", "Priority": 4 },
                    { "Name": "ECDHE-ECDSA-AES128-SHA", "Priority": 5 },
                    { "Name": "ECDHE-RSA-AES128-SHA", "Priority": 6 },
                    { "Name": "ECDHE-ECDSA-AES256-GCM-SHA384", "Priority": 7 },
                    { "Name": "ECDHE-RSA-AES256-GCM-SHA384", "Priority": 8 },
                    { "Name": "ECDHE-ECDSA-AES256-SHA384", "Priority": 9 },
                    { "Name": "ECDHE-RSA-AES256-SHA384", "Priority": 10 },
                    { "Name": "ECDHE-RSA-AES256-SHA", "Priority": 11 },
                    { "Name": "ECDHE-ECDSA-AES256-SHA", "Priority": 12 },
                  ],
                "Name": "ELBSecurityPolicy-FS-1-2-2019-08",
              },
          },
        "Arn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/web/3ff2fab33a993e0c",
        "Region": "us-east-1",
        "SecurityGroups": ["sg-000bbcc377444490b"],
        "TimeCreated": "2020-03-24T21:39:15.050Z",
        "WebAcl": null,
        "CanonicalHostedZonedId": "Z1H1FL5HABSF5",
        "ResourceType": "AWS.ELBV2.ApplicationLoadBalancer",
      }
  - Name: Default Ciphers
    ExpectedResult: false
    Resource:
      {
        "IpAddressType": "ipv4",
        "Type": "application",
        "Tags": { "Application": "Test" },
        "AvailabilityZones":
          [
            {
              "LoadBalancerAddresses": null,
              "ZoneName": "us-east-1b",
              "SubnetId": "subnet-05f7b81cc5d97e0e2",
            },
            {
              "ZoneName": "us-east-1a",
              "SubnetId": "subnet-07419606a40f4c414",
              "LoadBalancerAddresses": null,
            },
          ],
        "AccountId": "123456789012",
        "DNSName": "web-360787852.us-east-1.elb.amazonaws.com",
        "Listeners":
          [
            {
              "DefaultActions":
                [
                  {
                    "RedirectConfig": null,
                    "ForwardConfig":
                      {
                        "TargetGroups":
                          [
                            {
                              "TargetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/web/54eedfcacc3949ef",
                              "Weight": 1,
                            },
                          ],
                        "TargetGroupStickinessConfig":
                          { "Enabled": false, "DurationSeconds": null },
                      },
                    "AuthenticateOidcConfig": null,
                    "Order": null,
                    "TargetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/web/54eedfcacc3949ef",
                    "FixedResponseConfig": null,
                    "AuthenticateCognitoConfig": null,
                    "Type": "forward",
                  },
                ],
              "Port": 443,
              "Certificates":
                [
                  {
                    "IsDefault": null,
                    "CertificateArn": "arn:aws:acm:us-east-1:123456789012:certificate/10c4e713-9bb5-4ccf-aabc-1c9119370038",
                  },
                ],
              "Protocol": "HTTPS",
              "ListenerArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:listener/app/web/3ff2fab33a993e0c/995359b182328b77",
              "SslPolicy": "ELBSecurityPolicy-2016-08",
              "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/web/3ff2fab33a993e0c",
            },
          ],
        "ResourceId": "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/web/3ff2fab33a993e0c",
        "Scheme": "internet-facing",
        "VpcId": "vpc-0aa6688dd88484847",
        "State": { "Code": "active", "Reason": null },
        "Name": "web",
        "SSLPolicies":
          {
            "ELBSecurityPolicy-2016-08":
              {
                "Ciphers":
                  [
                    { "Priority": 1, "Name": "ECDHE-ECDSA-AES128-GCM-SHA256" },
                    { "Priority": 2, "Name": "ECDHE-RSA-AES128-GCM-SHA256" },
                    { "Priority": 3, "Name": "ECDHE-ECDSA-AES128-SHA256" },
                    { "Priority": 4, "Name": "ECDHE-RSA-AES128-SHA256" },
                    { "Priority": 5, "Name": "ECDHE-ECDSA-AES128-SHA" },
                    { "Priority": 6, "Name": "ECDHE-RSA-AES128-SHA" },
                    { "Priority": 7, "Name": "ECDHE-ECDSA-AES256-GCM-SHA384" },
                    { "Name": "ECDHE-RSA-AES256-GCM-SHA384", "Priority": 8 },
                    { "Name": "ECDHE-ECDSA-AES256-SHA384", "Priority": 9 },
                    { "Priority": 10, "Name": "ECDHE-RSA-AES256-SHA384" },
                    { "Priority": 11, "Name": "ECDHE-RSA-AES256-SHA" },
                    { "Name": "ECDHE-ECDSA-AES256-SHA", "Priority": 12 },
                    { "Priority": 13, "Name": "AES128-GCM-SHA256" },
                    { "Name": "AES128-SHA256", "Priority": 14 },
                    { "Priority": 15, "Name": "AES128-SHA" },
                    { "Name": "AES256-GCM-SHA384", "Priority": 16 },
                    { "Priority": 17, "Name": "AES256-SHA256" },
                    { "Priority": 18, "Name": "AES256-SHA" },
                  ],
                "SslProtocols": ["TLSv1", "TLSv1.1", "TLSv1.2"],
                "Name": "ELBSecurityPolicy-2016-08",
              },
          },
        "Arn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/web/3ff2fab33a993e0c",
        "Region": "us-east-1",
        "SecurityGroups": ["sg-000bbcc377444490b"],
        "TimeCreated": "2020-03-24T21:39:15.050Z",
        "WebAcl": null,
        "CanonicalHostedZonedId": "Z1H1FL5HABSF5",
        "ResourceType": "AWS.ELBV2.ApplicationLoadBalancer",
      }
  - Name: Default Ciphers Internal Load Balancer
    ExpectedResult: true
    Resource:
      {
        "IpAddressType": "ipv4",
        "Type": "application",
        "Tags": { "Application": "Test" },
        "AvailabilityZones":
          [
            {
              "LoadBalancerAddresses": null,
              "ZoneName": "us-east-1b",
              "SubnetId": "subnet-05f7b81cc5d97e0e2",
            },
            {
              "ZoneName": "us-east-1a",
              "SubnetId": "subnet-07419606a40f4c414",
              "LoadBalancerAddresses": null,
            },
          ],
        "AccountId": "123456789012",
        "DNSName": "web-360787852.us-east-1.elb.amazonaws.com",
        "Listeners":
          [
            {
              "DefaultActions":
                [
                  {
                    "RedirectConfig": null,
                    "ForwardConfig":
                      {
                        "TargetGroups":
                          [
                            {
                              "TargetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/web/54eedfcacc3949ef",
                              "Weight": 1,
                            },
                          ],
                        "TargetGroupStickinessConfig":
                          { "Enabled": false, "DurationSeconds": null },
                      },
                    "AuthenticateOidcConfig": null,
                    "Order": null,
                    "TargetGroupArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:targetgroup/web/54eedfcacc3949ef",
                    "FixedResponseConfig": null,
                    "AuthenticateCognitoConfig": null,
                    "Type": "forward",
                  },
                ],
              "Port": 443,
              "Certificates":
                [
                  {
                    "IsDefault": null,
                    "CertificateArn": "arn:aws:acm:us-east-1:123456789012:certificate/10c4e713-9bb5-4ccf-aabc-1c9119370038",
                  },
                ],
              "Protocol": "HTTPS",
              "ListenerArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:listener/app/web/3ff2fab33a993e0c/995359b182328b77",
              "SslPolicy": "ELBSecurityPolicy-2016-08",
              "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/web/3ff2fab33a993e0c",
            },
          ],
        "ResourceId": "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/web/3ff2fab33a993e0c",
        "Scheme": "internal",
        "VpcId": "vpc-0aa6688dd88484847",
        "State": { "Code": "active", "Reason": null },
        "Name": "web",
        "SSLPolicies":
          {
            "ELBSecurityPolicy-2016-08":
              {
                "Ciphers":
                  [
                    { "Priority": 1, "Name": "ECDHE-ECDSA-AES128-GCM-SHA256" },
                    { "Priority": 2, "Name": "ECDHE-RSA-AES128-GCM-SHA256" },
                    { "Priority": 3, "Name": "ECDHE-ECDSA-AES128-SHA256" },
                    { "Priority": 4, "Name": "ECDHE-RSA-AES128-SHA256" },
                    { "Priority": 5, "Name": "ECDHE-ECDSA-AES128-SHA" },
                    { "Priority": 6, "Name": "ECDHE-RSA-AES128-SHA" },
                    { "Priority": 7, "Name": "ECDHE-ECDSA-AES256-GCM-SHA384" },
                    { "Name": "ECDHE-RSA-AES256-GCM-SHA384", "Priority": 8 },
                    { "Name": "ECDHE-ECDSA-AES256-SHA384", "Priority": 9 },
                    { "Priority": 10, "Name": "ECDHE-RSA-AES256-SHA384" },
                    { "Priority": 11, "Name": "ECDHE-RSA-AES256-SHA" },
                    { "Name": "ECDHE-ECDSA-AES256-SHA", "Priority": 12 },
                    { "Priority": 13, "Name": "AES128-GCM-SHA256" },
                    { "Name": "AES128-SHA256", "Priority": 14 },
                    { "Priority": 15, "Name": "AES128-SHA" },
                    { "Name": "AES256-GCM-SHA384", "Priority": 16 },
                    { "Priority": 17, "Name": "AES256-SHA256" },
                    { "Priority": 18, "Name": "AES256-SHA" },
                  ],
                "SslProtocols": ["TLSv1", "TLSv1.1", "TLSv1.2"],
                "Name": "ELBSecurityPolicy-2016-08",
              },
          },
        "Arn": "arn:aws:elasticloadbalancing:us-east-1:123456789012:loadbalancer/app/web/3ff2fab33a993e0c",
        "Region": "us-east-1",
        "SecurityGroups": ["sg-000bbcc377444490b"],
        "TimeCreated": "2020-03-24T21:39:15.050Z",
        "WebAcl": null,
        "CanonicalHostedZonedId": "Z1H1FL5HABSF5",
        "ResourceType": "AWS.ELBV2.ApplicationLoadBalancer",
      }
  - Name: Observed - No Listeners len() issue
    ExpectedResult: false
    Resource:
      {
        "Listeners": null,
        "Scheme": "internet-facing",
        "SSLPolicies":
          {
            "ELBSecurityPolicy-2016-08":
              {
                "Ciphers":
                  [{ "Priority": 1, "Name": "ECDHE-ECDSA-AES128-GCM-SHA256" }],
                "SslProtocols": ["TLSv1", "TLSv1.1", "TLSv1.2"],
                "Name": "ELBSecurityPolicy-2016-08",
              },
          },
      }
  - Name: TLS 1.3 listeners
    ExpectedResult: true
    Resource:
      {
        "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/tls13/de81aaaa65555555",
        "DNSName": "tls13-46494243.us-west-2.elb.amazonaws.com",
        "CanonicalHostedZoneId": "Z1H1FL5HABSF5",
        "CreatedTime": "2023-04-17T23:46:54.550000+00:00",
        "LoadBalancerName": "tls13",
        "Scheme": "internet-facing",
        "VpcId": "vpc-043e0527f2d6372ea",
        "State": { "Code": "active" },
        "Type": "application",
        "AvailabilityZones":
          [
            {
              "ZoneName": "us-west-2a",
              "SubnetId": "subnet-0a42f65abd22d0d87",
              "LoadBalancerAddresses": [],
            },
            {
              "ZoneName": "us-west-2b",
              "SubnetId": "subnet-0aa42b18abd62e88f",
              "LoadBalancerAddresses": [],
            },
          ],
        "SecurityGroups": ["sg-0197ba84777a5858a"],
        "IpAddressType": "ipv4",
        "Listeners":
          [
            {
              "ListenerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:listener/app/tls13/de81aaaa65555555/5f992ca6d5368214",
              "LoadBalancerArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:loadbalancer/app/tls13/de81aaaa65555555",
              "Port": 443,
              "Protocol": "HTTPS",
              "Certificates":
                [
                  {
                    "CertificateArn": "arn:aws:acm:us-west-2:123456789012:certificate/517cb27d-03fb-4659-96a5-40592b25d977",
                  },
                ],
              "SslPolicy": "ELBSecurityPolicy-TLS13-1-2-2021-06",
              "DefaultActions":
                [
                  {
                    "Type": "forward",
                    "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/oktgname/67c62d09d6d23288",
                    "ForwardConfig":
                      {
                        "TargetGroups":
                          [
                            {
                              "TargetGroupArn": "arn:aws:elasticloadbalancing:us-west-2:123456789012:targetgroup/oktgname/67c62d09d6d23288",
                              "Weight": 1,
                            },
                          ],
                        "TargetGroupStickinessConfig": { "Enabled": false },
                      },
                  },
                ],
            },
          ],
        "SSLPolicies":
          {
            "ELBSecurityPolicy-TLS13-1-2-2021-06":
              {
                "SslProtocols": ["TLSv1.2", "TLSv1.3"],
                "Ciphers":
                  [
                    { "Name": "TLS_AES_128_GCM_SHA256", "Priority": 1 },
                    { "Name": "TLS_AES_256_GCM_SHA384", "Priority": 2 },
                    { "Name": "TLS_CHACHA20_POLY1305_SHA256", "Priority": 3 },
                    { "Name": "ECDHE-ECDSA-AES128-GCM-SHA256", "Priority": 4 },
                    { "Name": "ECDHE-RSA-AES128-GCM-SHA256", "Priority": 5 },
                    { "Name": "ECDHE-ECDSA-AES128-SHA256", "Priority": 6 },
                    { "Name": "ECDHE-RSA-AES128-SHA256", "Priority": 7 },
                    { "Name": "ECDHE-ECDSA-AES256-GCM-SHA384", "Priority": 8 },
                    { "Name": "ECDHE-RSA-AES256-GCM-SHA384", "Priority": 9 },
                    { "Name": "ECDHE-ECDSA-AES256-SHA384", "Priority": 10 },
                    { "Name": "ECDHE-RSA-AES256-SHA384", "Priority": 11 },
                  ],
                "Name": "ELBSecurityPolicy-TLS13-1-2-2021-06",
                "SupportedLoadBalancerTypes": ["application", "network"],
              },
          },
      }


# ------ paired body: aws_alb_ssl_policy.py ------

# https://docs.aws.amazon.com/elasticloadbalancing/latest/application/create-https-listener.html#describe-ssl-policies
# Requirements to be "safe": 1) TLSv1.2+ only; 2) Forward Secrecy

TLS_SAFE_POLICIES = {
    "ELBSecurityPolicy-FS-1-2-2019-08",
    "ELBSecurityPolicy-FS-1-2-Res-2019-08",
    "ELBSecurityPolicy-FS-1-2-Res-2020-10",
    "ELBSecurityPolicy-TLS13-1-2-2021-06",
    "ELBSecurityPolicy-TLS13-1-2-Res-2021-06",
    "ELBSecurityPolicy-TLS13-1-3-2021-06",
}


def policy(resource):
    # Ignore load balancers that aren't serving internet traffic
    if resource.get("Scheme") == "internal":
        return True

    return len(resource.get("Listeners") if resource.get("Listeners") else []) >= 1 and all(
        (each_policy in TLS_SAFE_POLICIES for each_policy in resource.get("SSLPolicies", {}).keys())
    )

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.