You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have defined an asset filter in a policy for scanning terraform-hcl that uses && requiring that both queries in the filter match in order for the check to run against a specific Terraform resource. The filter does not respect the && and will incorrectly run against Terraform code that only matches one side of the expression.
The check that is incorrectly executing contains the following asset filter:
In order for the check to run it should match both sides of the expression:
asset.platform == "terraform-hcl"
There should be one resource discovered with the nameLabel == "aws_account_alternate_contact"
What I see is that if I scan a folder that does not contain any aws_account_alternate_contact resources, the check runs. cnspec shell validates that the folder I am scanning does not contain any aws_account_alternate_contact resources:
policies:
- uid: aws-security-hub
name: AWS Security Hub
version: 1.0.0
scoring_system: 2
authors:
- name: Mondoo, Inc.
email: [email protected]
tags:
mondoo.com/platform: aws,cloud
mondoo.com/category: security
groups:
- title: AWS account controls
checks:
- uid: aws-security-hub-security-account-information-provided
- uid: aws-security-hub-security-account-part-of-organizations
- title: AWS Certificate Manager controls
checks:
- uid: aws-security-hub-acm-certificate-expiration-check
- uid: aws-security-hub-acm-certificate-rsa-check
- title: API Gateway controls
checks:
- uid: aws-security-hub-api-gw-execution-logging-enabled
- uid: aws-security-hub-api-gw-ssl-enabled
- uid: aws-security-hub-api-gw-xray-enabled
- uid: aws-security-hub-api-gw-associated-with-waf
- uid: aws-security-hub-api-gw-cache-encrypted
- uid: aws-security-hub-api-gwv2-authorization-type-configured
- uid: aws-security-hub-api-gwv2-access-logs-enabled
- title: AWS AppSync controls
checks:
- uid: aws-security-hub-appsync-logging-enabled
- title: Athena controls
checks:
- uid: aws-security-hub-athena-workgroup-encrypted-at-rest
- title: Autoscaling controls
checks:
- uid: aws-security-hub-autoscaling-group-elb-healthcheck-required
- uid: aws-security-hub-autoscaling-multiple-az
- uid: aws-security-hub-autoscaling-launchconfig-requires-imdsv2
- uid: aws-security-hub-autoscaling-launch-config-hop-limit
- uid: aws-security-hub-autoscaling-launch-config-public-ip-disabled
- uid: aws-security-hub-autoscaling-multiple-instance-types
- uid: aws-security-hub-autoscaling-launch-template
queries:
- uid: aws-security-hub-security-account-information-provided
title: '[Account.1] Security contact information should be provided for an AWS account'
impact: 50
docs:
desc: |
**Related requirements:** NIST.800-53.r5 CM-2, NIST.800-53.r5 CM-2(2)
**Category:** Identify > Resource Configuration
**Impact:** Medium
**Resource type:** `AWS::::Account`
This checks if an Amazon Web Services (AWS) account has security contact information. The check fails if security contact information is not provided for the account.
Alternate security contacts allow AWS to contact another person about issues with your account in case you're unavailable. Notifications can be from AWS Support, or other AWS service teams about security-related topics associated with your AWS account usage.
variants:
- uid: aws-security-hub-security-account-information-provided-api
- uid: aws-security-hub-security-account-information-provided-terraform-hcl
- uid: aws-security-hub-security-account-information-provided-terraform-plan
- uid: aws-security-hub-security-account-information-provided-api
filters: asset.platform == "aws"
mql: true
docs:
remediation:
- id: console
desc: |
#### Adding or updating alternate contacts
Alternate contacts allows AWS to contact another person about issues with your account, even if you're unavailable. The alternate contact doesn't have to be a specific person. You could instead add an email distribution list if you have a team that manages billing, operations and security related issues.
**To add or update alternate contacts**
1. Sign in to the **Account** page in the Billing and Cost Management console at https://console.aws.amazon.com/billing/home?#/account.
2. Under **Alternate contacts**, choose **Edit**.
3. Enter your updated information and choose **Update**.
- uid: aws-security-hub-security-account-information-provided-terraform-hcl
filters: asset.platform == "terraform-hcl" && terraform.resources.where( nameLabel == "aws_account_alternate_contact")
mql: terraform.resources.where( nameLabel == "aws_account_alternate_contact" ).one( arguments['alternate_contact_type'] == "SECURITY" )
docs:
remediation:
- id: terraform
desc: |
The `aws_account_alternate_contact` manages the specified alternate contact attached to an AWS Account.
```
resource "aws_account_alternate_contact" "security" {
alternate_contact_type = "SECURITY"
name = "Example"
title = "Example"
email_address = "[email protected]"
phone_number = "+1234567890"
}
```
- uid: aws-security-hub-security-account-information-provided-terraform-plan
filters: asset.platform == "terraform-plan" && terraform.plan.resourceChanges.any( type == "aws_account_alternate_contact" )
mql: terraform.plan.resourceChanges.where( type == "aws_account_alternate_contact" ).one( change.after['alternate_contact_type'] == "SECURITY" )
docs:
remediation:
- id: terraform
desc: |
The `aws_account_alternate_contact` manages the specified alternate contact attached to an AWS Account.
```
resource "aws_account_alternate_contact" "security" {
alternate_contact_type = "SECURITY"
name = "Example"
title = "Example"
email_address = "[email protected]"
phone_number = "+1234567890"
}
```
- uid: aws-security-hub-security-account-part-of-organizations
title: '[Account.2] AWS accounts should be part of an AWS Organizations organization'
impact: 80
docs:
desc: |
**Related requirements:** NIST.800-53.r5 CA-9(1), NIST.800-53.r5 CM-2
**Category:** Protect > Secure access management > Access control
**Impact:** High
**Resource type:** `AWS::::Account`
This checks if an AWS account is part of an organization managed through AWS Organizations. The check fails if the account is not part of an organization.
Organizations helps you centrally manage your environment as you scale your workloads on AWS. You can use multiple AWS accounts to isolate workloads that have specific security requirements, or to comply with frameworks such as HIPAA or PCI. By creating an organization, you can administer multiple accounts as a single unit and centrally manage their access to AWS services, resources, and Regions.
variants:
- uid: aws-security-hub-security-account-part-of-organizations-api
- uid: aws-security-hub-security-account-part-of-organizations-api
filters: asset.platform == "aws"
mql: aws.account.organization.masterAccountId != null
docs:
remediation:
- id: console
desc: |
To create a new organization and automatically add AWS accounts to it, see [Creating an organization](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_org_create.html) in the AWS Organizations User Guide. To add accounts to an existing organization, see [Inviting an AWS account to join your organization](https://docs.aws.amazon.com/organizations/latest/userguide/orgs_manage_accounts_invites.html) in the AWS Organizations User Guide.
- uid: aws-security-hub-acm-certificate-expiration-check
title: '[ACM.1] Imported and ACM-issued certificates should be renewed after a specified time period'
impact: 50
props:
- uid: acmDaysToExpiration
mql: return 30
docs:
desc: |
**Related requirements:** NIST.800-53.r5 SC-28(3), NIST.800-53.r5 SC-7(16)
**Category:** Protect > Data protection > Encryption of data in transit
**Impact:** Medium
**Resource type:** `AWS::ACM::Certificate`
This checks whether ACM certificates in your account are marked for expiration within 30 days. It checks both imported certificates and certificates provided by AWS Certificate Manager.
ACM can automatically renew certificates that use DNS validation. For certificates that use email validation, you must respond to a domain validation email. ACM does not automatically renew certificates that you import. You must renew imported certificates manually.
For more information about managed renewal for ACM certificates, see [Managed renewal for ACM certificates](https://docs.aws.amazon.com/acm/latest/userguide/managed-renewal.html) in the AWS Certificate Manager User Guide.
variants:
- uid: aws-security-hub-acm-certificate-expiration-check-api
- uid: aws-security-hub-acm-certificate-expiration-check-api
filters: asset.platform == "aws"
mql: aws.acm.certificates.where( status != /PENDING_VALIDATION/ ).all (notAfter - notBefore <= props.acmDaysToExpiration * time.day)
docs:
remediation:
- id: console
desc: |
ACM provides managed renewal for your SSL/TLS certificates issued by Amazon. This means that ACM either renews your certificates automatically (if you use DNS validation), or it sends you email notices when the certificate expiration approaches. These services are provided for both public and private ACM certificates.
**For domains validated by email**
When a certificate is 45 days from expiration, ACM sends to the domain owner an email for each domain name. To validate the domains and complete the renewal, you must respond to the email notifications.
For more information, see [Renewal for domains validated by email](https://docs.aws.amazon.com/acm/latest/userguide/email-renewal-validation.html) in the AWS Certificate Manager User Guide.
** For domains validated by DNS**
ACM automatically renews certificates that use DNS validation. 60 days before the expiration, ACM verifies that the certificate can be renewed.
If it cannot validate a domain name, then ACM sends a notification that manual validation is required. It sends these notifications 45 days, 30 days, 7 days, and 1 day before the expiration.
For more information, see [Renewal for domains validated by DNS](https://docs.aws.amazon.com/acm/latest/userguide/dns-renewal-validation.html) in the AWS Certificate Manager User Guide.
- uid: aws-security-hub-acm-certificate-rsa-check
title: '[ACM.2] RSA certificates managed by ACM should use a key length of at least 2,048 bits'
impact: 80
docs:
desc: |
**Category:** Identify > Inventory > Inventory services
**Impact:** High
**Resource type:** `AWS::ACM::Certificate`
This checks whether RSA certificates managed by AWS Certificate Manager use a key length of at least 2,048 bits. The check fails if the key length is smaller than 2,048 bits.
The strength of encryption directly correlates with key size. We recommend key lengths of at least 2,048 bits to protect your AWS resources as computing power becomes less expensive and servers become more advanced.
variants:
- uid: aws-security-hub-acm-certificate-rsa-check-api
- uid: aws-security-hub-acm-certificate-rsa-check-api
filters: asset.platform == "aws"
mql: true
docs:
remediation:
- id: console
desc: |
The minimum key length for RSA certificates issued by ACM is already 2,048 bits. For instructions on issuing new RSA certificates with ACM, see [Issuing and managing certificates](https://docs.aws.amazon.com/acm/latest/userguide/gs.html) in the AWS Certificate Manager User Guide.
While ACM allows you to import certificates with shorter key lengths, you must use keys of at least 2,048 bits to pass this control. You can't change the key length after importing a certificate. Instead, you must delete certificates with a key length smaller than 2,048 bits. For more information about importing certificates into ACM, see [Prerequisites for importing certificates](https://docs.aws.amazon.com/acm/latest/userguide/import-certificate-prerequisites.html) in the AWS Certificate Manager User Guide.
- uid: aws-security-hub-api-gw-execution-logging-enabled
title: '[APIGateway.1] API Gateway REST and WebSocket API execution logging should be enabled'
impact: 50
docs:
desc: |
**Related requirements:** NIST.800-53.r5 AC-4(26), NIST.800-53.r5 AU-10, NIST.800-53.r5 AU-12, NIST.800-53.r5 AU-2, NIST.800-53.r5 AU-3, NIST.800-53.r5 AU-6(3), NIST.800-53.r5 AU-6(4), NIST.800-53.r5 CA-7, NIST.800-53.r5 SC-7(9), NIST.800-53.r5 SI-7(8)
**Category:** Identify > Logging
**Impact:** Medium
**Resource type:** `AWS::ApiGateway::Stage`, `AWS::ApiGatewayV2::Stage`
This checks whether all stages of an Amazon API Gateway REST or WebSocket API have logging enabled. The check fails if logging is not enabled for all methods of a stage or if loggingLevel is neither ERROR nor INFO.
API Gateway REST or WebSocket API stages should have relevant logs enabled. API Gateway REST and WebSocket API execution logging provides detailed records of requests made to API Gateway REST and WebSocket API stages. The stages include API integration backend responses, Lambda authorizer responses, and the requestId for AWS integration endpoints.
variants:
- uid: aws-security-hub-api-gw-execution-logging-enabled-api
- uid: aws-security-hub-api-gw-execution-logging-enabled-api
filters: asset.platform == "aws"
mql: aws.apigateway.restApis.all( stages.all( methodSettings.values.all( _["LoggingLevel"] == "ERROR" || _["LoggingLevel"] == "INFO" )))
docs:
remediation:
- id: console
desc: |
To enable logging for REST and WebSocket API operations, see [Set up CloudWatch API logging using the API Gateway console](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-logging.html#set-up-access-logging-using-console) in the *API Gateway Developer Guide.*
- uid: aws-security-hub-api-gw-ssl-enabled
title: '[APIGateway.2] API Gateway REST API stages should be configured to use SSL certificates for backend authentication'
impact: 50
docs:
desc: |
This checks whether Amazon API Gateway REST API stages have SSL certificates configured. Backend systems use these certificates to authenticate that incoming requests are from API Gateway.
API Gateway REST API stages should be configured with SSL certificates to allow backend systems to authenticate that requests originate from API Gateway.
**Related requirements:** NIST.800-53.r5 AC-17(2), NIST.800-53.r5 AC-4, NIST.800-53.r5 IA-5(1), NIST.800-53.r5 SC-12(3), NIST.800-53.r5 SC-13, NIST.800-53.r5 SC-23, NIST.800-53.r5 SC-23(3), NIST.800-53.r5 SC-7(4), NIST.800-53.r5 SC-8, NIST.800-53.r5 SC-8(1), NIST.800-53.r5 SC-8(2), NIST.800-53.r5 SI-7(6)
variants:
- uid: aws-security-hub-api-gw-ssl-enabled-api
- uid: aws-security-hub-api-gw-ssl-enabled-api
filters: asset.platform == "aws"
mql: true
docs:
remediation:
- id: console
desc: |
For detailed instructions on how to generate and configure API Gateway REST API SSL certificates, see [Generate and configure an SSL certificate for backend authentication](https://docs.aws.amazon.com/apigateway/latest/developerguide/getting-started-client-side-ssl-authentication.html) in the *API Gateway Developer Guide.*
- uid: aws-security-hub-api-gw-xray-enabled
title: '[APIGateway.3] API Gateway REST API stages should have AWS X-Ray tracing enabled'
impact: 10
docs:
desc: |
**Related requirements:** NIST.800-53.r5 CA-7
**Category:** Detect > Detection services
**Severity:** Low
**Resource type:** `AWS::ApiGateway::Stage`
This checks whether AWS X-Ray active tracing is enabled for your Amazon API Gateway REST API stages.
X-Ray active tracing enables a more rapid response to performance changes in the underlying infrastructure. Changes in performance could result in a lack of availability of the API. X-Ray active tracing provides real-time metrics of user requests that flow through your API Gateway REST API operations and connected services.
variants:
- uid: aws-security-hub-api-gw-xray-enabled-api
- uid: aws-security-hub-api-gw-xray-enabled-api
filters: asset.platform == "aws"
mql: true
docs:
remediation:
- id: console
desc: |
For detailed instructions on how to enable X-Ray active tracing for API Gateway REST API operations, see [Amazon API Gateway active tracing support for AWS X-Ray](https://docs.aws.amazon.com/xray/latest/devguide/xray-services-apigateway.html) in the AWS X-Ray Developer Guide.
- uid: aws-security-hub-api-gw-associated-with-waf
title: '[APIGateway.4] API Gateway should be associated with a WAF Web ACL'
impact: 50
docs:
desc: |
**Related requirements:** NIST.800-53.r5 AC-4(21)
**Category:** Protect > Protective services
**Severity:** Medium
**Resource type:** `AWS::ApiGateway::Stage`
This checks whether an API Gateway stage uses an AWS WAF web access control list (ACL). This check fails if an AWS WAF web ACL is not attached to a REST API Gateway stage.
AWS WAF is a web application firewall that helps protect web applications and APIs from attacks. It enables you to configure an ACL, which is a set of rules that allow, block, or count web requests based on customizable web security rules and conditions that you define. Ensure that your API Gateway stage is associated with an AWS WAF web ACL to help protect it from malicious attacks.
variants:
- uid: aws-security-hub-api-gw-associated-with-waf-api
- uid: aws-security-hub-api-gw-associated-with-waf-api
filters: asset.platform == "aws"
mql: true
docs:
remediation:
- id: console
desc: |
For information on how to use the API Gateway console to associate an AWS WAF Regional web ACL with an existing API Gateway API stage, see [Using AWS WAF to protect your APIs](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-control-access-aws-waf.html) in the API Gateway Developer Guide.
- uid: aws-security-hub-api-gw-cache-encrypted
title: '[APIGateway.5] API Gateway REST API cache data should be encrypted at rest'
impact: 50
docs:
desc: |
**Related requirements:** NIST.800-53.r5 CA-9(1), NIST.800-53.r5 CM-3(6), NIST.800-53.r5 SC-13, NIST.800-53.r5 SC-28, NIST.800-53.r5 SC-28(1), NIST.800-53.r5 SC-7(10), NIST.800-53.r5 SI-7(6)
**Category:** Data protection > Encryption of data at rest
**Severity:** Medium
**Resource type:** `AWS::ApiGateway::Stage`
This checks whether all methods in API Gateway REST API stages that have cache enabled are encrypted. The check fails if any method in an API Gateway REST API stage is configured to cache and the cache is not encrypted. Security Hub evaluates the encryption of a particular method only when caching is enabled for that method.
Encrypting data at rest reduces the risk of data stored on disk being accessed by a user not authenticated to AWS. It adds another set of access controls to limit unauthorized users ability access the data. For example, API permissions are required to decrypt the data before it can be read.
API Gateway REST API caches should be encrypted at rest for an added layer of security.
variants:
- uid: aws-security-hub-api-gw-cache-encrypted-api
- uid: aws-security-hub-api-gw-cache-encrypted-api
filters: asset.platform == "aws"
mql: true
docs:
remediation:
- id: console
desc: |
To configure API caching for a stage, see [Enable Amazon API Gateway caching](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-caching.html#enable-api-gateway-caching) in the API Gateway Developer Guide. In Cache Settings, choose Encrypt cache data.
- uid: aws-security-hub-api-gwv2-authorization-type-configured
title: '[APIGateway.8] API Gateway routes should specify an authorization type'
impact: 50
docs:
desc: |
**Related requirements:** NIST.800-53.r5 AC-3, NIST.800-53.r5 CM-2, NIST.800-53.r5 CM-2(2)
**Category:** Protect > Secure Access Management
**Severity:** Medium
**Resource type:** `AWS::ApiGatewayV2::Route`
This control checks if Amazon API Gateway routes have an authorization type. The control fails if the API Gateway route does not specify an authorization type.
API Gateway supports multiple mechanisms for controlling and managing access to your API. By specifying an authorization type, you can restrict access to your API to only authorized users or processes.
variants:
- uid: aws-security-hub-api-gwv2-authorization-type-configured-api
- uid: aws-security-hub-api-gwv2-authorization-type-configured-api
filters: asset.platform == "aws"
mql: true
docs:
remediation:
- id: console
desc: |
To set an authorization type for HTTP APIs, see [Controlling and managing access to an HTTP API in API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/http-api-access-control.html) in the API Gateway Developer Guide. To set an authorization type for WebSocket APIs, see [Controlling and managing access to a WebSocket API](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-websocket-api-control-access.html) in API Gateway in the API Gateway Developer Guide.
- uid: aws-security-hub-api-gwv2-access-logs-enabled
title: '[APIGateway.9] Access logging should be configured for API Gateway V2 Stages'
impact: 50
docs:
desc: |
**Related requirements:** NIST.800-53.r5 AC-4(26), NIST.800-53.r5 AU-10, NIST.800-53.r5 AU-12, NIST.800-53.r5 AU-2, NIST.800-53.r5 AU-3, NIST.800-53.r5 AU-6(3), NIST.800-53.r5 AU-6(4), NIST.800-53.r5 CA-7, NIST.800-53.r5 SC-7(9), NIST.800-53.r5 SI-7(8)
**Category:** Identify > Logging
**Severity:** Medium
**Resource type:** `AWS::ApiGatewayV2::Stage`
This checks if Amazon API Gateway V2 stages have access logging configured. The check fails if access log settings aren't defined.
API Gateway access logs provide detailed information about who has accessed your API and how the caller accessed the API. These logs are useful for applications such as security and access audits and forensics investigation. Enable these access logs to analyze traffic patterns and to troubleshoot issues.
For additional best practices, see [Monitoring REST APIs](https://docs.aws.amazon.com/apigateway/latest/developerguide/rest-api-monitor.html) in the API Gateway Developer Guide.
variants:
- uid: aws-security-hub-api-gwv2-access-logs-enabled-api
- uid: aws-security-hub-api-gwv2-access-logs-enabled-api
filters: asset.platform == "aws"
mql: true
docs:
remediation:
- id: console
desc: |
To set up access logging, see [Set up CloudWatch API logging using the API Gateway console](https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-logging.html#set-up-access-logging-using-console) in the API Gateway Developer Guide.
- uid: aws-security-hub-appsync-logging-enabled
title: '[AppSync.2] AWS AppSync should have request-level and field-level logging turned on'
impact: 50
docs:
desc: |
**Category:** Identify > Logging
**Severity:** Medium
**Resource type:** `AWS::AppSync::GraphQLApi`
This checks whether an AWS AppSync API has request-level and field-level logging turned on. This check fails if request-level logging isn't turned on or if the field resolver log level is set to **None**.
You can use logging and metrics to identify, troubleshoot, and optimize your GraphQL queries. Turning on logging for AWS AppSync GraphQL helps you get detailed information about API requests and responses, identify and respond to issues, and comply with regulatory requirements.
variants:
- uid: aws-security-hub-appsync-logging-enabled-api
- uid: aws-security-hub-appsync-logging-enabled-api
filters: asset.platform == "aws"
mql: true
docs:
remediation:
- id: console
desc: |
To turn on logging for AWS AppSync, see [Setup and configuration](https://docs.aws.amazon.com/appsync/latest/devguide/monitoring.html#setup-and-configuration) in the AWS AppSync Developer Guide. Choose **Error** or **All** for the field-level logging level.
- uid: aws-security-hub-athena-workgroup-encrypted-at-rest
title: '[Athena.1] Athena workgroups should be encrypted at rest'
impact: 50
docs:
desc: |
**Related requirements:** NIST.800-53.r5 CA-9(1), NIST.800-53.r5 CM-3(6), NIST.800-53.r5 SC-13, NIST.800-53.r5 SC-28, NIST.800-53.r5 SC-28(1), NIST.800-53.r5 SC-7(10), NIST.800-53.r5 SI-7(6)
**Category:** Protect > Data protection > Encryption of data at rest
**Severity:** Medium
**Resource type:** `AWS::Athena::WorkGroup`
This checks if an Athena workgroup is encrypted at rest. The check fails if an Athena workgroup is not encrypted at rest.
In Athena, you can create workgroups for running queries for teams, applications, or different workloads. Each workgroup has a setting to enable encryption on all queries. You have the option to use server-side encryption with Amazon Simple Storage Service (Amazon S3) managed keys, server-side encryption with AWS Key Management Service (AWS KMS) keys, or client-side encryption with customer managed KMS keys. Data at rest refers to any data that's stored in persistent, non-volatile storage for any duration. Encryption helps you protect the confidentiality of such data, reducing the risk that an unauthorized user can access it.
variants:
- uid: aws-security-hub-athena-workgroup-encrypted-at-rest-api
- uid: aws-security-hub-athena-workgroup-encrypted-at-rest-api
filters: asset.platform == "aws"
mql: true
docs:
remediation:
- id: console
desc: |
To enable encryption at rest for Athena workgroups, see [Edit a workgroup](https://docs.aws.amazon.com/athena/latest/ug/workgroups-create-update-delete.html#editing-workgroups) in the Amazon Athena User Guide. In the **Query Result Configuration** section, select **Encrypt query results.**
- uid: aws-security-hub-autoscaling-group-elb-healthcheck-required
title: '[AutoScaling.1] Auto Scaling groups associated with a Classic Load Balancer should use load balancer health checks'
impact: 10
docs:
desc: |
**Related requirements:** PCI DSS v3.2.1/2.2, NIST.800-53.r5 CA-7, NIST.800-53.r5 CP-2(2), NIST.800-53.r5 SI-2
**Category:** Identify > Inventory
**Severity:** Low
**Resource type:** `AWS::AutoScaling::AutoScalingGroup`
This checks whether your Auto Scaling groups that are associated with a Classic Load Balancer are using Elastic Load Balancing health checks.
This ensures that the group can determine an instance's health based on additional tests provided by the load balancer. Using Elastic Load Balancing health checks can help support the availability of applications that use EC2 Auto Scaling groups.
variants:
- uid: aws-security-hub-autoscaling-group-elb-healthcheck-required-api
- uid: aws-security-hub-autoscaling-group-elb-healthcheck-required-api
filters: asset.platform == "aws"
mql: aws.autoscaling.groups.where(loadBalancerNames.length > 0).all( healthCheckType == "ELB" )
docs:
remediation:
- id: console
desc: |
To add Elastic Load Balancing health checks, see [Add Elastic Load Balancing health checks](https://docs.aws.amazon.com/autoscaling/ec2/userguide/as-add-elb-healthcheck.html#as-add-elb-healthcheck-console) in the Amazon EC2 Auto Scaling User Guide.
- uid: aws-security-hub-autoscaling-multiple-az
title: '[AutoScaling.2] Amazon EC2 Auto Scaling group should cover multiple Availability Zones'
impact: 50
docs:
desc: |
**Related requirements:** NIST.800-53.r5 CP-10, NIST.800-53.r5 CP-2(2), NIST.800-53.r5 CP-6(2), NIST.800-53.r5 SC-36, NIST.800-53.r5 SC-5(2), NIST.800-53.r5 SI-13(5)
**Category:** Recover > Resilience > High Availability
**Severity:** Medium
**Resource type:** `AWS::AutoScaling::AutoScalingGroup`
This checks whether an Auto Scaling group spans multiple Availability Zones. The check fails if an Auto Scaling group does not span multiple Availability Zones.
Amazon EC2 Auto Scaling groups can be configured to use multiple Availability Zones. An Auto Scaling group with a single Availability Zone is preferred in some use cases, such as batch-jobs or when inter-AZ transfer costs need to be kept to a minimum. However, an Auto Scaling group that does not span multiple Availability Zones will not launch instances in another Availability Zone to compensate if the configured single Availability Zone becomes unavailable.
variants:
- uid: aws-security-hub-autoscaling-multiple-az-api
- uid: aws-security-hub-autoscaling-multiple-az-api
filters: asset.platform == "aws"
mql: |
# TO DO
true
docs:
remediation:
- id: console
desc: |
For information on how to add Availability Zones to an existing auto scaling group, see [Availability zones](https://docs.aws.amazon.com/autoscaling/ec2/userguide/as-add-availability-zone.html) in the Amazon EC2 Auto Scaling User Guide.
- uid: aws-security-hub-autoscaling-launchconfig-requires-imdsv2
title: '[AutoScaling.3] Auto Scaling group launch configurations should configure EC2 instances to require Instance Metadata Service Version 2 (IMDSv2)'
impact: 80
docs:
desc: |
**Related requirements:** NIST.800-53.r5 AC-3, NIST.800-53.r5 AC-3(15), NIST.800-53.r5 AC-3(7), NIST.800-53.r5 AC-6, NIST.800-53.r5 CA-9(1), NIST.800-53.r5 CM-2
**Category:** Protect > Secure network configuration
**Severity:** High
**Resource type:** `AWS::AutoScaling::LaunchConfiguration`
This checks whether IMDSv2 is enabled on all instances launched by Amazon EC2 Auto Scaling groups. The check fails if the Instance Metadata Service (IMDS) version is not included in the launch configuration or if both IMDSv1 and IMDSv2 are enabled.
IMDS provides data about your instance that you can use to configure or manage the running instance.
Version 2 of the IMDS adds new protections that weren't available in IMDSv1 to further safeguard your EC2 instances.
variants:
- uid: aws-security-hub-autoscaling-launchconfig-requires-imdsv2-api
- uid: aws-security-hub-autoscaling-launchconfig-requires-imdsv2-terraform-hcl
- uid: aws-security-hub-autoscaling-launchconfig-requires-imdsv2-terraform-plan
- uid: aws-security-hub-autoscaling-launchconfig-requires-imdsv2-api
filters: asset.platform == "aws"
mql: |
# TO DO
true
docs:
remediation:
- id: console
desc: |
For information on how to add Availability Zones to an existing auto scaling group, see [Availability zones](https://docs.aws.amazon.com/autoscaling/ec2/userguide/as-add-availability-zone.html) in the Amazon EC2 Auto Scaling User Guide.
- uid: aws-security-hub-autoscaling-launchconfig-requires-imdsv2-terraform-hcl
filters: asset.platform == "terraform-hcl" && terraform.resources.any( nameLabel == "aws_launch_configuration" )
mql: terraform.resources.where( nameLabel == "aws_launch_configuration" ).all( blocks.where( type == "metadata_options" ).all( arguments['http_endpoint'] == 'disabled' || arguments['http_tokens'] == 'required' ))
docs:
remediation:
- id: terraform
desc: |
#### Require the use of IMDSv2 when requesting instance metadata
```
resource "aws_launch_configuration" "as_conf" {
image_id = data.aws_ami.ubuntu2204.id
instance_type = "m4.large"
metadata_options {
http_tokens = "required"
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_autoscaling_group" "bar" {
name = "terraform-asg-example"
max_size = 5
min_size = 2
launch_configuration = aws_launch_configuration.as_conf.name
}
```
#### Disable instance metadata
```
resource "aws_launch_configuration" "as_conf" {
image_id = data.aws_ami.ubuntu2204.id
instance_type = "m4.large"
metadata_options {
http_endpoint = "disabled"
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_autoscaling_group" "bar" {
name = "terraform-asg-example"
max_size = 5
min_size = 2
launch_configuration = aws_launch_configuration.as_conf.name
}
```
- uid: aws-security-hub-autoscaling-launchconfig-requires-imdsv2-terraform-plan
filters: asset.platform == "terraform-plan" && terraform.plan.resourceChanges.any( type == "aws_launch_configuration" )
mql: terraform.plan.resourceChanges.where( type == "aws_launch_configuration" ).all( change.after['metadata_options'][0]['http_tokens'] == "required" || change.after['metadata_options'][0]['http_endpoint'] == "disabled" )
docs:
remediation:
- id: terraform
desc: |
#### Require the use of IMDSv2 when requesting instance metadata
```
resource "aws_launch_configuration" "as_conf" {
image_id = data.aws_ami.ubuntu2204.id
instance_type = "m4.large"
metadata_options {
http_tokens = "required"
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_autoscaling_group" "bar" {
name = "terraform-asg-example"
max_size = 5
min_size = 2
launch_configuration = aws_launch_configuration.as_conf.name
}
```
#### Disable instance metadata
```
resource "aws_launch_configuration" "as_conf" {
image_id = data.aws_ami.ubuntu2204.id
instance_type = "m4.large"
metadata_options {
http_endpoint = "disabled"
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_autoscaling_group" "bar" {
name = "terraform-asg-example"
max_size = 5
min_size = 2
launch_configuration = aws_launch_configuration.as_conf.name
}
```
- uid: aws-security-hub-autoscaling-launch-config-hop-limit
title: '[AutoScaling.4] Auto Scaling group launch configuration should not have a metadata response hop limit greater than 1'
impact: 80
docs:
desc: |
**Related requirements:** NIST.800-53.r5 CA-9(1), NIST.800-53.r5 CM-2, NIST.800-53.r5 CM-2(2)
**Category:** Protect > Secure network configuration
**Severity:** High
**Resource type:** `AWS::AutoScaling::LaunchConfiguration`
This checks the number of network hops that a metadata token can travel. The check fails if the metadata response hop limit is greater than 1.
The Instance Metadata Service (IMDS) provides metadata information about an Amazon EC2 instance and is useful for application configuration. Restricting the HTTP PUT response for the metadata service to only the EC2 instance protects the IMDS from unauthorized use.
The Time To Live (TTL) field in the IP packet is reduced by one on every hop. This reduction can be used to ensure that the packet does not travel outside EC2. IMDSv2 protects EC2 instances that may have been misconfigured as open routers, layer 3 firewalls, VPNs, tunnels, or NAT devices, which prevents unauthorized users from retrieving metadata. With IMDSv2, the PUT response that contains the secret token cannot travel outside the instance because the default metadata response hop limit is set to 1. However, if this value is greater than 1, the token can leave the EC2 instance.
variants:
- uid: aws-security-hub-autoscaling-launch-config-hop-limit-api
- uid: aws-security-hub-autoscaling-launch-config-hop-limit-terraform-hcl
- uid: aws-security-hub-autoscaling-launch-config-hop-limit-terraform-plan
- uid: aws-security-hub-autoscaling-launch-config-hop-limit-api
filters: asset.platform == "aws"
mql: |
# TO DO
true
docs:
remediation:
- id: console
desc: |
To modify the metadata response hop limit for an existing launch configuration, see [Modify instance metadata options for existing instances](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-options.html#configuring-IMDS-existing-instances) in the Amazon EC2 User Guide for Linux Instances.
- uid: aws-security-hub-autoscaling-launch-config-hop-limit-terraform-hcl
filters: asset.platform == "terraform-hcl" && terraform.resources.any( nameLabel == "aws_launch_configuration" )
mql: terraform.resources.where( nameLabel == "aws_launch_configuration" ).all( blocks.where( type == "metadata_options" ).one( arguments['http_put_response_hop_limit'] <= 1 ))
docs:
remediation:
- id: terraform
desc: |
#### Set the desired HTTP PUT response hop limit for instance metadata requests.
```
resource "aws_launch_configuration" "as_conf" {
image_id = data.aws_ami.ubuntu2204.id
instance_type = "m4.large"
metadata_options {
http_put_response_hop_limit = 1
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_autoscaling_group" "bar" {
name = "terraform-asg-example"
max_size = 5
min_size = 2
launch_configuration = aws_launch_configuration.as_conf.name
}
```
- uid: aws-security-hub-autoscaling-launch-config-hop-limit-terraform-plan
filters: asset.platform == "terraform-plan" && terraform.plan.resourceChanges.any( type == "aws_launch_configuration" )
mql: terraform.plan.resourceChanges.where( type == "aws_launch_configuration" ).all( change.after['metadata_options'][0]['http_put_response_hop_limit'] <= 1 )
docs:
remediation:
- id: terraform
desc: |
#### Set the desired HTTP PUT response hop limit for instance metadata requests.
```
resource "aws_launch_configuration" "as_conf" {
image_id = data.aws_ami.ubuntu2204.id
instance_type = "m4.large"
metadata_options {
http_put_response_hop_limit = 1
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_autoscaling_group" "bar" {
name = "terraform-asg-example"
max_size = 5
min_size = 2
launch_configuration = aws_launch_configuration.as_conf.name
}
```
- uid: aws-security-hub-autoscaling-launch-config-public-ip-disabled
title: '[Autoscaling.5] Amazon EC2 instances launched using Auto Scaling group launch configurations should not have Public IP addresses'
impact: 80
docs:
desc: |
**Related requirements:** NIST.800-53.r5 AC-21, NIST.800-53.r5 AC-3, NIST.800-53.r5 AC-3(7), NIST.800-53.r5 AC-4, NIST.800-53.r5 AC-4(21), NIST.800-53.r5 AC-6, NIST.800-53.r5 SC-7, NIST.800-53.r5 SC-7(11), NIST.800-53.r5 SC-7(16), NIST.800-53.r5 SC-7(20), NIST.800-53.r5 SC-7(21), NIST.800-53.r5 SC-7(3), NIST.800-53.r5 SC-7(4), NIST.800-53.r5 SC-7(9)
**Category:** Protect > Secure network configuration
**Severity:** High
**Resource type:** `AWS::AutoScaling::LaunchConfiguration`
This checks whether an Auto Scaling group's associated launch configuration assigns a public IP address to the group's instances. The check fails if the associated launch configuration assigns a public IP address.
Amazon EC2 instances in an Auto Scaling group launch configuration should not have an associated public IP address, except for in limited edge cases. Amazon EC2 instances should only be accessible from behind a load balancer instead of being directly exposed to the internet.
variants:
- uid: aws-security-hub-autoscaling-launch-config-public-ip-disabled-api
- uid: aws-security-hub-autoscaling-launch-config-public-ip-disabled-terraform-hcl
- uid: aws-security-hub-autoscaling-launch-config-public-ip-disabled-terraform-plan
- uid: aws-security-hub-autoscaling-launch-config-public-ip-disabled-api
filters: asset.platform == "aws"
mql: |
# TO DO
true
docs:
remediation:
- id: console
desc: |
An Auto Scaling group is associated with one launch configuration at a time. You cannot modify a launch configuration after you create it. To change the launch configuration for an Auto Scaling group, use an existing launch configuration as the basis for a new launch configuration. Then, update the Auto Scaling group to use the new launch configuration. For step-by-step instructions, see [Change the launch configuration for an Auto Scaling group](https://docs.aws.amazon.com/autoscaling/ec2/userguide/change-launch-config.html) in the Amazon EC2 Auto Scaling User Guide. When creating the new launch configuration, under **Additional configuration**, for **Advanced details**, **IP address type**, choose **Do not assign a public IP address to any instances.**
After you change the launch configuration, Auto Scaling launches new instances with the new configuration options. Existing instances aren't affected. To update an existing instance, we recommend that you refresh your instance, or allow automatic scaling to gradually replace older instances with newer instances based on your termination policies. For more information about updating Auto Scaling instances, see [Update Auto Scaling instances](https://docs.aws.amazon.com/autoscaling/ec2/userguide/update-auto-scaling-group.html#update-auto-scaling-instances) in the Amazon EC2 Auto Scaling User Guide.
- uid: aws-security-hub-autoscaling-launch-config-public-ip-disabled-terraform-hcl
filters: asset.platform == "terraform-hcl" && terraform.resources.any( nameLabel == "aws_launch_configuration" )
mql: terraform.resources.where( nameLabel == "aws_launch_configuration" ).all( arguments['associate_public_ip_address'] != true )
docs:
remediation:
- id: terraform
desc: |
#### Set associate_public_ip_address to `false` in the aws_launch_configuration resource
```
resource "aws_launch_configuration" "as_conf" {
image_id = data.aws_ami.ubuntu2204.id
instance_type = "m4.large"
associate_public_ip_address = false
}
resource "aws_autoscaling_group" "bar" {
name = "terraform-asg-example"
max_size = 5
min_size = 2
launch_configuration = aws_launch_configuration.as_conf.name
}
```
- uid: aws-security-hub-autoscaling-launch-config-public-ip-disabled-terraform-plan
filters: asset.platform == "terraform-plan" && terraform.plan.resourceChanges.any( type == "aws_launch_configuration" )
mql: terraform.plan.resourceChanges.where( type == "aws_launch_configuration" ).all( change.after['associate_public_ip_address'] != true )
docs:
remediation:
- id: terraform
desc: |
#### Set associate_public_ip_address to `false` in the aws_launch_configuration resource
```
resource "aws_launch_configuration" "as_conf" {
image_id = data.aws_ami.ubuntu2204.id
instance_type = "m4.large"
associate_public_ip_address = false
}
resource "aws_autoscaling_group" "bar" {
name = "terraform-asg-example"
max_size = 5
min_size = 2
launch_configuration = aws_launch_configuration.as_conf.name
}
```
- uid: aws-security-hub-autoscaling-multiple-instance-types
title: '[AutoScaling.6] Auto Scaling groups should use multiple instance types in multiple Availability Zones'
impact: 50
docs:
desc: |
**Related requirements:** NIST.800-53.r5 CA-9(1), NIST.800-53.r5 CM-2, NIST.800-53.r5 CM-2(2)
**Category:** Identify > Resource Configuration
**Severity:** Medium
**Resource type:** `AWS::AutoScaling::AutoScalingGroup`
This checks whether an Amazon EC2 Auto Scaling group is created from an EC2 launch template. This check fails if an Amazon EC2 Auto Scaling group is not created with a launch template or if a launch template is not specified in a mixed instances policy.
An EC2 Auto Scaling group can be created from either an EC2 launch template or a launch configuration. However, using a launch template to create an Auto Scaling group ensures that you have access to the latest features and improvements.
variants:
- uid: aws-security-hub-autoscaling-multiple-instance-types-api
- uid: aws-security-hub-autoscaling-multiple-instance-types-terraform-hcl
- uid: aws-security-hub-autoscaling-multiple-instance-types-terraform-plan
- uid: aws-security-hub-autoscaling-multiple-instance-types-api
filters: asset.platform == "aws"
mql: |
# TO DO
true
docs:
remediation:
- id: console
desc: |
To create an Auto Scaling group with multiple instance types, see [Auto Scaling groups with multiple instance types and purchase options](https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-mixed-instances-groups.html) in the Amazon EC2 Auto Scaling User Guide.
- uid: aws-security-hub-autoscaling-multiple-instance-types-terraform-hcl
filters: asset.platform == "terraform-hcl" && terraform.resources.any( nameLabel == "aws_launch_configuration" )
mql: |
# TO DO
true
docs:
remediation:
- id: terraform
desc: |
#### Set the desired HTTP PUT response hop limit for instance metadata requests.
```
resource "aws_launch_configuration" "as_conf" {
image_id = data.aws_ami.ubuntu2204.id
instance_type = "m4.large"
associate_public_ip_address = false
}
resource "aws_autoscaling_group" "bar" {
name = "terraform-asg-example"
max_size = 5
min_size = 2
launch_configuration = aws_launch_configuration.as_conf.name
}
```
- uid: aws-security-hub-autoscaling-multiple-instance-types-terraform-plan
filters: asset.platform == "terraform-plan" && terraform.plan.resourceChanges.any( type == "aws_launch_configuration" )
mql: |
# TO DO
true
docs:
remediation:
- id: terraform
desc: |
#### Set the desired HTTP PUT response hop limit for instance metadata requests.
```
resource "aws_launch_configuration" "as_conf" {
image_id = data.aws_ami.ubuntu2204.id
instance_type = "m4.large"
associate_public_ip_address = false
}
resource "aws_autoscaling_group" "bar" {
name = "terraform-asg-example"
max_size = 5
min_size = 2
launch_configuration = aws_launch_configuration.as_conf.name
}
```
- uid: aws-security-hub-autoscaling-launch-template
title: '[AutoScaling.9] Amazon EC2 Auto Scaling groups should use Amazon EC2 launch templates'
impact: 50
docs:
desc: |
**Related requirements:** NIST.800-53.r5 CA-9(1), NIST.800-53.r5 CM-2, NIST.800-53.r5 CM-2(2)
**Category:** Identify > Resource Configuration
**Severity:** Medium
**Resource type:** `AWS::AutoScaling::AutoScalingGroup`
This control checks whether an Amazon EC2 Auto Scaling group is created from an EC2 launch template. This control fails if an Amazon EC2 Auto Scaling group is not created with a launch template or if a launch template is not specified in a mixed instances policy.
An EC2 Auto Scaling group can be created from either an EC2 launch template or a launch configuration. However, using a launch template to create an Auto Scaling group ensures that you have access to the latest features and improvements.
variants:
- uid: aws-security-hub-autoscaling-launch-template-api
- uid: aws-security-hub-autoscaling-launch-template-terraform-hcl
- uid: aws-security-hub-autoscaling-launch-template-terraform-plan
- uid: aws-security-hub-autoscaling-launch-template-api
filters: asset.platform == "aws"
mql: |
# TO DO
true
docs:
remediation:
- id: console
desc: |
To create an Auto Scaling group with multiple instance types, see [Auto Scaling groups with multiple instance types and purchase options](https://docs.aws.amazon.com/autoscaling/ec2/userguide/ec2-auto-scaling-mixed-instances-groups.html) in the Amazon EC2 Auto Scaling User Guide.
- uid: aws-security-hub-autoscaling-launch-template-terraform-hcl
filters: asset.platform == "terraform-hcl" && terraform.resources.any( nameLabel == "aws_autoscaling_group" )
mql: terraform.resources.where( nameLabel == "aws_autoscaling_group" ).all( arguments['launch_configuration'] )
docs:
remediation:
- id: terraform
desc: |
#### Set the desired HTTP PUT response hop limit for instance metadata requests.
```
resource "aws_launch_configuration" "as_conf" {
image_id = data.aws_ami.ubuntu2204.id
instance_type = "m4.large"
associate_public_ip_address = false
}
resource "aws_autoscaling_group" "bar" {
name = "terraform-asg-example"
max_size = 5
min_size = 2
launch_configuration = aws_launch_configuration.as_conf.name
}
```
- uid: aws-security-hub-autoscaling-launch-template-terraform-plan
filters: asset.platform == "terraform-plan" && terraform.plan.resourceChanges.any( type == "aws_autoscaling_group" )
mql: terraform.plan.resourceChanges.where( type == "aws_autoscaling_group" ).all( change.after['launch_configuration'] )
docs:
remediation:
- id: terraform
desc: |
#### Set the desired HTTP PUT response hop limit for instance metadata requests.
```
resource "aws_launch_configuration" "as_conf" {
image_id = data.aws_ami.ubuntu2204.id
instance_type = "m4.large"
associate_public_ip_address = false
}
resource "aws_autoscaling_group" "bar" {
name = "terraform-asg-example"
max_size = 5
min_size = 2
launch_configuration = aws_launch_configuration.as_conf.name
}
```
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots or CLI Output
If applicable, add screenshots or the CLI output to help explain your problem.
Desktop (please complete the following information):
OS: [e.g. macOS]
OS Version: [e.g. 13.0]
Browser if applicable: [e.g. Chrome, Firefox]
Browser Version: [e.g. 106]
Additional context
Add any other context about the problem here.
The text was updated successfully, but these errors were encountered:
.where is not a truthy condition as you use in filters: asset.platform == "terraform-hcl" && terraform.resources.where( nameLabel == "aws_account_alternate_contact")
I updated the filter to filters: asset.platform == "terraform-hcl" && terraform.resources.any( nameLabel == "aws_account_alternate_contact") and the issue was resolved.
Describe the bug
I have defined an asset filter in a policy for scanning
terraform-hcl
that uses&&
requiring that both queries in the filter match in order for the check to run against a specific Terraform resource. The filter does not respect the&&
and will incorrectly run against Terraform code that only matches one side of the expression.The check that is incorrectly executing contains the following asset filter:
In order for the check to run it should match both sides of the expression:
asset.platform == "terraform-hcl"
nameLabel == "aws_account_alternate_contact"
What I see is that if I scan a folder that does not contain any
aws_account_alternate_contact
resources, the check runs. cnspec shell validates that the folder I am scanning does not contain anyaws_account_alternate_contact
resources:NOTE THIS DOES NOT HAPPEN WHEN SCANNING TERRAFORM PLAN FILES
To Reproduce
create
terraform/autoscaling/main.tf
Create security policy
Expected behavior
A clear and concise description of what you expected to happen.
Screenshots or CLI Output
If applicable, add screenshots or the CLI output to help explain your problem.
Desktop (please complete the following information):
Additional context
Add any other context about the problem here.
The text was updated successfully, but these errors were encountered: