checkov icon indicating copy to clipboard operation
checkov copied to clipboard

CKV2_AWS_32 False positive with terraform-aws-modules/cloudfront/aws

Open strangeman opened this issue 2 years ago • 3 comments

Describe the issue Checkov raises CKV2_AWS_32 even if response_headers_policy_id included

Examples Sample code:

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "5.18.1"
    }
  }

  required_version = "~> 1.3"
}

provider "aws" {
  region = "us-east-2"
}


data "aws_cloudfront_response_headers_policy" "Managed-CORS-with-preflight-and-SecurityHeadersPolicy" {
  name = "Managed-CORS-with-preflight-and-SecurityHeadersPolicy"
}

module "example-com" {
  #checkov:skip=CKV2_AWS_47:WONTFIX:Not related to the current issue
  #checkov:skip=CKV2_AWS_42:WONTFIX:Not related to the current issue
  #checkov:skip=CKV_AWS_174:WONTFIX:Not related to the current issue
  source  = "terraform-aws-modules/cloudfront/aws"
  version = "~> 3.0"

  aliases          = ["example.com"]
  retain_on_delete = "false"
  price_class      = "PriceClass_All"
  enabled          = "true"
  http_version     = "http2"
  is_ipv6_enabled  = "true"

  default_cache_behavior = {
    allowed_methods            = ["GET", "HEAD"]
    compress                   = "true"
    default_ttl                = "0"
    max_ttl                    = "0"
    min_ttl                    = "0"
    smooth_streaming           = "false"
    target_origin_id           = "example.com"
    viewer_protocol_policy     = "https-only"
    use_forwarded_values       = false
    response_headers_policy_id = data.aws_cloudfront_response_headers_policy.Managed-CORS-with-preflight-and-SecurityHeadersPolicy.id
  }

  origin = {
    something = {
      domain_name = "something.example.com"
      custom_origin_config = {
        http_port              = 80
        https_port             = 443
        origin_protocol_policy = "match-viewer"
        origin_ssl_protocols   = ["TLSv1", "TLSv1.1", "TLSv1.2"]
      }
    }
  }
}

terraform plan clearly shows that response_headers_policy_id is set for aws_cloudfront_distribution:

terraform plan
data.aws_cloudfront_response_headers_policy.Managed-CORS-with-preflight-and-SecurityHeadersPolicy: Reading...
data.aws_cloudfront_response_headers_policy.Managed-CORS-with-preflight-and-SecurityHeadersPolicy: Read complete after 1s [id=eaab4381-ed33-4a86-88ca-d9558dc6cd63]

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # module.example-com.aws_cloudfront_distribution.this[0] will be created
  + resource "aws_cloudfront_distribution" "this" {
      + aliases                        = [
          + "example.com",
        ]
      + arn                            = (known after apply)
      + caller_reference               = (known after apply)
      + domain_name                    = (known after apply)
      + enabled                        = true
      + etag                           = (known after apply)
      + hosted_zone_id                 = (known after apply)
      + http_version                   = "http2"
      + id                             = (known after apply)
      + in_progress_validation_batches = (known after apply)
      + is_ipv6_enabled                = true
      + last_modified_time             = (known after apply)
      + price_class                    = "PriceClass_All"
      + retain_on_delete               = false
      + staging                        = false
      + status                         = (known after apply)
      + tags_all                       = (known after apply)
      + trusted_key_groups             = (known after apply)
      + trusted_signers                = (known after apply)
      + wait_for_deployment            = true

      + default_cache_behavior {
          + allowed_methods            = [
              + "GET",
              + "HEAD",
            ]
          + cached_methods             = [
              + "GET",
              + "HEAD",
            ]
          + compress                   = true
          + default_ttl                = 0
          + max_ttl                    = 0
          + min_ttl                    = 0
          + response_headers_policy_id = "eaab4381-ed33-4a86-88ca-d9558dc6cd63"    <----- CKV2_AWS_32 false-positive
          + smooth_streaming           = false
          + target_origin_id           = "example.com"
          + trusted_key_groups         = (known after apply)
          + trusted_signers            = (known after apply)
          + viewer_protocol_policy     = "https-only"
        }

      + origin {
          + connection_attempts = 3
          + connection_timeout  = 10
          + domain_name         = "something.example.com"
          + origin_id           = "something"

          + custom_origin_config {
              + http_port                = 80
              + https_port               = 443
              + origin_keepalive_timeout = 5
              + origin_protocol_policy   = "match-viewer"
              + origin_read_timeout      = 30
              + origin_ssl_protocols     = [
                  + "TLSv1",
                  + "TLSv1.1",
                  + "TLSv1.2",
                ]
            }
        }

      + restrictions {
          + geo_restriction {
              + locations        = (known after apply)
              + restriction_type = "none"
            }
        }

      + viewer_certificate {
          + cloudfront_default_certificate = true
          + minimum_protocol_version       = "TLSv1"
        }
    }

Plan: 1 to add, 0 to change, 0 to destroy.

But checkov -d . -o github_failed_only --download-external-modules "terraform-aws-modules/cloudfront/aws:~>3.0" shows CKV2_AWS_32 violation

### terraform scan results:

|    | check_id    | file                                                                                        | resource                                            | check_name                                                            | guideline                                            |
|----|-------------|---------------------------------------------------------------------------------------------|-----------------------------------------------------|-----------------------------------------------------------------------|------------------------------------------------------|
|  0 | CKV2_AWS_32 | /.external_modules/github.com/terraform-aws-modules/terraform-aws-cloudfront/v3.2.1/main.tf | module.example-com.aws_cloudfront_distribution.this | Ensure CloudFront distribution has a response headers policy attached | https://docs.bridgecrew.io/docs/bc_aws_networking_65 |

Version (please complete the following information):

  • Checkov Version 2.4.50
  • CloudFront module version v3.2.1

strangeman avatar Sep 27 '23 12:09 strangeman

Looks like checkov cannot resolve the dependency graph for this module. In this case default_cache_behavior is set through a variable, not directly, and checkov fails to resolve it.

digraph {
        compound = "true"
        newrank = "true"
        subgraph "root" {
                ...
                "[root] module.example-com.aws_cloudfront_distribution.this (expand)" -> "[root] module.example-com.var.default_cache_behavior (expand)"
                ...
                "[root] module.example-com.var.default_cache_behavior (expand)" -> "[root] data.aws_cloudfront_response_headers_policy.Managed-CORS-with-preflight-and-SecurityHeadersPolicy (expand)"
                "[root] module.example-com.var.default_cache_behavior (expand)" -> "[root] module.example-com (expand)"
                ...
}

strangeman avatar Sep 28 '23 07:09 strangeman

I also have a resource defined with a default cache behaviour's response_headers_policy_id set to the ID from a data.aws_cloudfront_response_headers_policy source, and the check still fails (runs on the planfile). no module being used, just explicit resources, but still no dice.

tarfeef101 avatar Dec 18 '23 16:12 tarfeef101

Thanks for contributing to Checkov! We've automatically marked this issue as stale to keep our issues list tidy, because it has not had any activity for 6 months. It will be closed in 14 days if no further activity occurs. Commenting on this issue will remove the stale tag. If you want to talk through the issue or help us understand the priority and context, feel free to add a comment or join us in the Checkov slack channel at codifiedsecurity.slack.com Thanks!

stale[bot] avatar Jun 15 '24 17:06 stale[bot]