Repository: bridgecrewio/checkov

Issue:
CKV_AWS_174 incorrect reporting
CKV_AWS_174 is being triggered in our terraform code even though we have the viewer certificate set to use TLSv.1.2. Snippet of our code here:

viewer_certificate {
   acm_certificate_arn = aws_acm_certificate.cert.arn
   ssl_support_method       = "sni-only"
   minimum_protocol_version = "TLSv1.2_2019" 
}


Steps to reproduce the behavior:
Running checkov on our terraform code

**Expected behavior**
This check should be passed



**Additional context**
It looks to me like the issue is in the code between lines 17 and 19. I dont think based on the terraform documentation and the if statements that it would ever pass if using an acm certificate

https://github.com/bridgecrewio/checkov/blob/master/checkov/terraform/checks/resource/aws/CloudfrontTLS12.py



Discussion:
Hi @jgreaves91 you are correct, the check should be adjusted, as a workaround you could set `cloudfront_default_certificate = false` and then the check should pass. Do you want to fix it? Then I can give you some pointers, what you have to do 💪 
Thanks for reporting @jgreaves91 !

We'd happily accept a contribution on this if you're willing!

Resolving patch:
diff --git a/checkov/terraform/checks/resource/aws/CloudfrontTLS12.py b/checkov/terraform/checks/resource/aws/CloudfrontTLS12.py
--- a/checkov/terraform/checks/resource/aws/CloudfrontTLS12.py
+++ b/checkov/terraform/checks/resource/aws/CloudfrontTLS12.py
@@ -12,18 +12,18 @@ def __init__(self):
 
     def scan_resource_conf(self, conf):
         if "viewer_certificate" in conf.keys():
-            # check if cloudfront_default_certificate is true then this could use less than tls 1.2
             viewer_certificate = conf["viewer_certificate"][0]
-            if 'cloudfront_default_certificate' in viewer_certificate:
-                #is not using the default certificate
-                if viewer_certificate["cloudfront_default_certificate"] is not True:
-                    #these protocol versions
-                    if "minimum_protocol_version" in viewer_certificate:
-                        protocol=viewer_certificate["minimum_protocol_version"][0]
-                        if protocol in ['TLSv1.2_2018', 'TLSv1.2_2019', 'TLSv1.2_2021']:
-                            return CheckResult.PASSED
-
-        #No cert specified so using default which can be less that tls 1.2
+            # check if cloudfront_default_certificate is true then this could use less than tls 1.2
+            if ("cloudfront_default_certificate" in viewer_certificate and viewer_certificate
+                    ["cloudfront_default_certificate"][0] is not True) or (
+                    'minimum_protocol_version' in viewer_certificate):
+                # is not using the default certificate
+                if 'minimum_protocol_version' in viewer_certificate:
+                    protocol = viewer_certificate["minimum_protocol_version"][0]
+                    # these protocol versions
+                    if protocol in ['TLSv1.2_2018', 'TLSv1.2_2019', 'TLSv1.2_2021']:
+                        return CheckResult.PASSED
+        # No cert specified so using default which can be less that tls 1.2
         return CheckResult.FAILED
 
     def get_inspected_key(self):
@@ -34,4 +34,4 @@ def get_expected_values(self):
         return ['TLSv1.2_2018', 'TLSv1.2_2019', 'TLSv1.2_2021']
 
 
-check = CloudFrontTLS12()
\ No newline at end of file
+check = CloudFrontTLS12()


Test patch:
diff --git a/tests/terraform/checks/resource/aws/example_CloudfrontTLS12/main.tf b/tests/terraform/checks/resource/aws/example_CloudfrontTLS12/main.tf
--- a/tests/terraform/checks/resource/aws/example_CloudfrontTLS12/main.tf
+++ b/tests/terraform/checks/resource/aws/example_CloudfrontTLS12/main.tf
@@ -421,3 +421,110 @@ resource "aws_cloudfront_distribution" "pass" {
     minimum_protocol_version = "TLSv1.2_2018"
   }
 }
+
+resource "aws_cloudfront_distribution" "pass1" {
+  origin {
+    domain_name = aws_s3_bucket.b.bucket_regional_domain_name
+    origin_id   = local.s3_origin_id
+
+    s3_origin_config {
+      origin_access_identity = "origin-access-identity/cloudfront/ABCDEFG1234567"
+    }
+  }
+
+  enabled             = true
+  is_ipv6_enabled     = true
+  comment             = "Some comment"
+  default_root_object = "index.html"
+
+  logging_config {
+    include_cookies = false
+    bucket          = "mylogs.s3.amazonaws.com"
+    prefix          = "myprefix"
+  }
+
+  aliases = ["mysite.example.com", "yoursite.example.com"]
+
+  default_cache_behavior {
+    allowed_methods  = ["DELETE", "GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT"]
+    cached_methods   = ["GET", "HEAD"]
+    target_origin_id = local.s3_origin_id
+
+    forwarded_values {
+      query_string = false
+
+      cookies {
+        forward = "none"
+      }
+    }
+
+    viewer_protocol_policy = "allow-all"
+    min_ttl                = 0
+    default_ttl            = 3600
+    max_ttl                = 86400
+  }
+
+  # Cache behavior with precedence 0
+  ordered_cache_behavior {
+    path_pattern     = "/content/immutable/*"
+    allowed_methods  = ["GET", "HEAD", "OPTIONS"]
+    cached_methods   = ["GET", "HEAD", "OPTIONS"]
+    target_origin_id = local.s3_origin_id
+
+    forwarded_values {
+      query_string = false
+      headers      = ["Origin"]
+
+      cookies {
+        forward = "none"
+      }
+    }
+
+    min_ttl                = 0
+    default_ttl            = 86400
+    max_ttl                = 31536000
+    compress               = true
+    viewer_protocol_policy = "redirect-to-https"
+  }
+
+  # Cache behavior with precedence 1
+  ordered_cache_behavior {
+    path_pattern     = "/content/*"
+    allowed_methods  = ["GET", "HEAD", "OPTIONS"]
+    cached_methods   = ["GET", "HEAD"]
+    target_origin_id = local.s3_origin_id
+
+    forwarded_values {
+      query_string = false
+
+      cookies {
+        forward = "none"
+      }
+    }
+
+    min_ttl                = 0
+    default_ttl            = 3600
+    max_ttl                = 86400
+    compress               = true
+    viewer_protocol_policy = "redirect-to-https"
+  }
+
+  price_class = "PriceClass_200"
+
+  restrictions {
+    geo_restriction {
+      restriction_type = "whitelist"
+      locations        = ["US", "CA", "GB", "DE"]
+    }
+  }
+
+  tags = {
+    Environment = "production"
+  }
+
+  viewer_certificate {
+    acm_certificate_arn = aws_acm_certificate.cert.arn
+	ssl_support_method = "sni-only"
+	minimum_protocol_version = "TLSv1.2_2019"
+  }
+}
diff --git a/tests/terraform/checks/resource/aws/test_CloudFrontTLS12.py b/tests/terraform/checks/resource/aws/test_CloudFrontTLS12.py
--- a/tests/terraform/checks/resource/aws/test_CloudFrontTLS12.py
+++ b/tests/terraform/checks/resource/aws/test_CloudFrontTLS12.py
@@ -17,6 +17,7 @@ def test(self):
 
         passing_resources = {
             "aws_cloudfront_distribution.pass",
+            "aws_cloudfront_distribution.pass1",
         }
         failing_resources = {
             "aws_cloudfront_distribution.fail",
@@ -27,7 +28,7 @@ def test(self):
         passed_check_resources = set([c.resource for c in report.passed_checks])
         failed_check_resources = set([c.resource for c in report.failed_checks])
 
-        self.assertEqual(summary["passed"], 1)
+        self.assertEqual(summary["passed"], 2)
         self.assertEqual(summary["failed"], 3)
         self.assertEqual(summary["skipped"], 0)
         self.assertEqual(summary["parsing_errors"], 0)