> ## Documentation Index
> Fetch the complete documentation index at: https://cloudanix.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# AWS ACM Certificates With Wildcard Domain Names

### More Info:

Ensure that ACM single domain name certificates are used instead of wildcard certificates within your AWS account in order to follow security best practices and protect each domain/subdomain with its own unique private key. An AWS ACM wildcard certificate matches any first level subdomain or hostname in a domain.

### Risk Level

Low

### Address

Security

### Compliance Standards

* APRA CPS 234 (Australia)
* BSI C5 (Germany)
* Brazil LGPD
* CCPA / CPRA (California)
* CIS Critical Security Controls v8
* CMMC 2.0
* CSA Cloud Controls Matrix v4
* DPDPA
* Digital Operational Resilience Act (EU)
* Essential 8
* ISO/IEC 27017
* ISO/IEC 27018
* ISO/IEC 27701
* KSA PDPL
* MAS Technology Risk Management (Singapore)
* MITRE ATT\&CK (Cloud)
* NIS2 Directive
* NIST
* NIST SP 800-171
* NYDFS 23 NYCRR 500
* SWIFT Customer Security Controls Framework
* Sarbanes-Oxley IT General Controls
* StateRAMP
* UK NCSC Cyber Assessment Framework

### Triage and Remediation

<Tabs>
  <Tab title="Cause">
    ### Check Cause

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        1. Log in to the AWS Management Console and navigate to the API Gateway dashboard.

        2. In the APIs list, select the API you want to check.

        3. In the API's settings, navigate to the "Custom Domain Names" section. Here, you will see a list of all custom domain names associated with your API.

        4. Check the ACM Certificate column for each custom domain name. If a certificate has a wildcard (\*) in its domain name, it means that the certificate is configured with a wildcard domain name.
      </Accordion>

      <Accordion title="Using CLI">
        1. First, you need to install and configure AWS CLI on your local machine. You can do this by following the instructions provided by AWS. Make sure you have the necessary permissions to access the resources.

        2. Once the AWS CLI is set up, you can use the following command to list all the ACM Certificates:

           ```
           aws acm list-certificates --region your-region
           ```

           Replace 'your-region' with the region where your ACM Certificates are located. This command will return a list of all the ACM Certificates in the specified region.

        3. To check if any of these certificates have wildcard domain names, you can use the following command:

           ```
           aws acm describe-certificate --certificate-arn your-certificate-arn --region your-region
           ```

           Replace 'your-certificate-arn' with the ARN of the certificate you want to check and 'your-region' with the region where the certificate is located. This command will return the details of the specified certificate.

        4. In the output of the above command, look for the 'DomainName' field. If the value of this field starts with '*', then the certificate has a wildcard domain name. For example, a value of '*.example.com' indicates a wildcard domain name.
      </Accordion>

      <Accordion title="Using Python">
        1. **Setup AWS SDK (Boto3) in Python Environment:**
           First, you need to set up AWS SDK (Boto3) in your Python environment. You can install it using pip:
           ```
           pip install boto3
           ```
           After installing boto3, configure your AWS credentials. You can configure your credentials either by setting up environment variables or by using AWS CLI.

        2. **List ACM Certificates:**
           Use the `list_certificates` method provided by the ACM client in boto3 to list all the certificates. Here is a sample script:
           ```python theme={null}
           import boto3

           def list_acm_certificates():
               acm_client = boto3.client('acm')
               response = acm_client.list_certificates()
               return response['CertificateSummaryList']

           certificates = list_acm_certificates()
           print(certificates)
           ```
           This script will print all the ACM certificates.

        3. **Check for Wildcard Domain Names:**
           Now, iterate over the certificates and check if any certificate has a wildcard domain name. A wildcard domain name starts with "\*.". Here is the updated script:
           ```python theme={null}
           import boto3

           def list_acm_certificates():
               acm_client = boto3.client('acm')
               response = acm_client.list_certificates()
               return response['CertificateSummaryList']

           def check_wildcard_domain(certificates):
               wildcard_certs = []
               for cert in certificates:
                   if cert['DomainName'].startswith('*.'):
                       wildcard_certs.append(cert)
               return wildcard_certs

           certificates = list_acm_certificates()
           wildcard_certs = check_wildcard_domain(certificates)
           print(wildcard_certs)
           ```
           This script will print all the ACM certificates with wildcard domain names.

        4. **Check API Gateway for ACM Certificates:**
           Finally, check if any of the ACM certificates with wildcard domain names are used in API Gateway. Use the `get_rest_apis` method provided by the API Gateway client in boto3. Here is the final script:
           ```python theme={null}
           import boto3

           def list_acm_certificates():
               acm_client = boto3.client('acm')
               response = acm_client.list_certificates()
               return response['CertificateSummaryList']

           def check_wildcard_domain(certificates):
               wildcard_certs = []
               for cert in certificates:
                   if cert['DomainName'].startswith('*.'):
                       wildcard_certs.append(cert)
               return wildcard_certs

           def check_api_gateway(wildcard_certs):
               api_gateway_client = boto3.client('apigateway')
               response = api_gateway_client.get_rest_apis()
               for api in response['items']:
                   if 'certificateId' in api and api['certificateId'] in [cert['CertificateArn'] for cert in wildcard_certs]:
                       print(f"API Gateway {api['name']} is using ACM certificate with wildcard domain name")

           certificates = list_acm_certificates()
           wildcard_certs = check_wildcard_domain(certificates)
           check_api_gateway(wildcard_certs)
           ```
           This script will print the names of all API Gateways that are using ACM certificates with wildcard domain names.
      </Accordion>
    </AccordionGroup>
  </Tab>

  <Tab title="Remediation">
    ### Remediation

    <AccordionGroup>
      <Accordion title="Using Console" defaultOpen="true">
        The misconfiguration of AWS ACM certificates with wildcard domain names can be remediated by following these steps using the AWS console:

        1. Log in to the AWS Management Console.
        2. Navigate to the AWS Certificate Manager (ACM) service.
        3. Click on the certificate that has a wildcard domain name misconfiguration.
        4. Click on the "Actions" button and select "Delete" to delete the certificate.
        5. Click on "Request a certificate" to create a new certificate.
        6. In the "Add domain names" section, enter the domain name without the wildcard character.
        7. Click on "Add another name" to add additional domain names if necessary.
        8. Select the validation method to validate the domain ownership.
        9. Click on "Review and request" to review the certificate request details.
        10. Click on "Confirm and request" to submit the certificate request.
        11. Once the certificate is issued, update the DNS records for the domain names to point to the new certificate.

        By following these steps, the misconfiguration of AWS ACM certificates with wildcard domain names can be remediated.

        #
      </Accordion>

      <Accordion title="Using CLI">
        The misconfiguration of AWS ACM Certificates with Wildcard Domain Names can be remediated by following these steps using AWS CLI:

        1. Open your terminal and install AWS CLI if it's not already installed.

        2. Run the following command to list all the certificates in your AWS account:

           ```
           aws acm list-certificates
           ```

        3. Identify the certificate that has a wildcard domain name and make a note of its ARN.

        4. Run the following command to describe the certificate:

           ```
           aws acm describe-certificate --certificate-arn <certificate-arn>
           ```

           Replace `<certificate-arn>` with the ARN of the certificate you noted in step 3.

        5. Check if the certificate is associated with any AWS resources like an Elastic Load Balancer (ELB) or a CloudFront distribution. If yes, note down their ARNs as well.

        6. Run the following command to delete the certificate:

           ```
           aws acm delete-certificate --certificate-arn <certificate-arn>
           ```

           Replace `<certificate-arn>` with the ARN of the certificate you noted in step 3.

        7. If the certificate was associated with any AWS resources, update them with a new certificate that does not have a wildcard domain name. You can create a new certificate using AWS ACM or import an existing certificate.

        8. Once the new certificate is associated with all the required resources, the remediation is complete.

        Note: Deleting a certificate may cause a brief outage for the associated resources. Make sure to plan the remediation during a maintenance window to minimize the impact on your users.
      </Accordion>

      <Accordion title="Using Python">
        The misconfiguration is related to AWS ACM (Amazon Certificate Manager) certificates with wildcard domain names. This misconfiguration occurs when an ACM certificate is created with a wildcard domain name, but the certificate is not associated with the appropriate resources.

        To remediate this misconfiguration, you can use the following steps:

        1. First, you need to identify the ACM certificates that have wildcard domain names and are not associated with the appropriate resources. You can use the AWS SDK for Python (Boto3) to achieve this.

        ```
        import boto3

        acm = boto3.client('acm')

        response = acm.list_certificates(CertificateStatuses=['ISSUED'])

        for certificate in response['CertificateSummaryList']:
            if certificate['DomainName'].startswith('*.'):
                certificate_arn = certificate['CertificateArn']
                response = acm.list_tags_for_certificate(CertificateArn=certificate_arn)
                tags = response['Tags']
                if 'Resource' not in [tag['Key'] for tag in tags]:
                    print(f"Certificate {certificate_arn} is not associated with any resource.")
        ```

        2. Once you have identified the ACM certificates that are not associated with the appropriate resources, you can associate them with the appropriate resources. For example, if you have an ACM certificate with a wildcard domain name "\*.example.com", you can associate it with your Elastic Load Balancer (ELB) using the following code:

        ```
        import boto3

        acm = boto3.client('acm')
        elbv2 = boto3.client('elbv2')

        certificate_arn = 'arn:aws:acm:us-east-1:123456789012:certificate/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'

        response = elbv2.describe_load_balancers(Names=['my-load-balancer'])

        load_balancer_arn = response['LoadBalancers'][0]['LoadBalancerArn']

        response = acm.list_tags_for_certificate(CertificateArn=certificate_arn)
        tags = response['Tags']

        if 'Resource' not in [tag['Key'] for tag in tags]:
            acm.add_tags_to_certificate(
                CertificateArn=certificate_arn,
                Tags=[
                    {
                        'Key': 'Resource',
                        'Value': 'LoadBalancer'
                    },
                    {
                        'Key': 'ResourceArn',
                        'Value': load_balancer_arn
                    }
                ]
            )
        ```

        This code associates the ACM certificate with the ELB by adding two tags to the certificate: "Resource" with the value "LoadBalancer" and "ResourceArn" with the value of the ELB ARN.

        By following these steps, you can remediate the misconfiguration related to AWS ACM certificates with wildcard domain names.
      </Accordion>

      <Accordion title="Using Terraform">
        ```hcl theme={null}
        # Request a non-wildcard ACM certificate for the exact API Gateway custom domain
        resource "aws_acm_certificate" "api_gateway_domain_cert" {
          domain_name               = "API_GATEWAY_FQDN_EXAMPLE" # e.g. "api.example.com"
          validation_method         = "DNS"
          subject_alternative_names = [] # Do NOT include any wildcard names like "*.example.com"

          tags = {
            Name = "API Gateway certificate for API_GATEWAY_FQDN_EXAMPLE"
          }
        }

        # (Example) Route 53 DNS validation – remove or adapt if you validate differently
        data "aws_route53_zone" "api_zone" {
          name         = "PARENT_DNS_ZONE" # e.g. "example.com."
          private_zone = false
        }

        resource "aws_route53_record" "api_gateway_cert_validation" {
          for_each = {
            for dvo in aws_acm_certificate.api_gateway_domain_cert.domain_validation_options :
            dvo.domain_name => {
              name   = dvo.resource_record_name
              record = dvo.resource_record_value
              type   = dvo.resource_record_type
            }
          }

          zone_id = data.aws_route53_zone.api_zone.zone_id
          name    = each.value.name
          type    = each.value.type
          ttl     = 300

          records = [each.value.record]
        }

        resource "aws_acm_certificate_validation" "api_gateway_domain_cert_validation" {
          certificate_arn         = aws_acm_certificate.api_gateway_domain_cert.arn
          validation_record_fqdns = [for r in aws_route53_record.api_gateway_cert_validation : r.fqdn]
        }

        # Attach the non-wildcard ACM certificate to API Gateway custom domain
        # (REST APIs – use aws_apigatewayv2_domain_name for HTTP/WebSocket APIs)
        resource "aws_api_gateway_domain_name" "api_custom_domain" {
          domain_name = "API_GATEWAY_FQDN_EXAMPLE" # same FQDN as the cert

          regional_certificate_arn = aws_acm_certificate_validation.api_gateway_domain_cert_validation.certificate_arn
          endpoint_configuration {
            types = ["REGIONAL"]
          }
        }
        ```

        Changing from a wildcard ACM certificate ARN to this single-domain ACM certificate ARN may briefly disrupt custom-domain traffic during certificate swap, but does not force replacement of the API Gateway domain resource itself.

        For verification, `terraform plan` should show creation of `aws_acm_certificate.api_gateway_domain_cert` (and its validation resources) and an in-place update of `aws_api_gateway_domain_name.api_custom_domain` changing the certificate ARN from the wildcard certificate to the new single-domain certificate.
      </Accordion>
    </AccordionGroup>
  </Tab>
</Tabs>

### Additional Reading:

* [https://docs.aws.amazon.com/acm/latest/userguide/acm-certificate.html](https://docs.aws.amazon.com/acm/latest/userguide/acm-certificate.html)
