Repository: bridgecrewio/checkov

Issue:
CKV_AWS_103 - Mentioned Checkov Checks producing an Exception, when the Listener protocol is HTTP (ALB).
Background of the Issue :  

We have been using mentioned Checkov inbuilt checks/policy ID (CKV_AWS_103/ BC_AWS_GENERAL_43) for connection requests in AWS Load balancer.  it was working fine when application team using the Module, "aws_lb_listener" "redirect" will only enable when application team users "HTTPS" Protocol. The particular issue is being presented when we attempt "HTTP" Protocol (Development Environment)

Sample Module snippet (AWS Load Balancer Listener ) (Re-direct Action) :- 

resource "aws_lb_listener" "redirect_http_listeneter" {
load_balancer_arn = aws_lb.front_end.arn
port = "80"
protocol = "HTTP" 
}

default action {
   type = "redirect"

redirect {
  port =  "443"
  }
}
}

ISSUE :- 
Exception Occur :- [If application team used the protocol HTTP]   

Exception message sample 
"[MainThread][ERROR] Failed to run check: Ensure the load balancer is using TLS1.2 for configuration:{'alpn_policy':[None],'arn':['arn:aws:elasticloadbalancing:**********:listener/app/dev-opsmanager-ec2-alb/******/*****],'certicate_arn':[None], 'default_action':

In bridgecrewio github,  [ checkov/terraform/checks/resource/aws/AppLoadBalancerTLS12.py ]
supports only HTTPS and it not producing any proper results, if we application team using HTTP.  So require your support to tweak globally in the in-built check ID. 

checkov version : 2.0.704

kindly let me know any other additional inputs require from our end.








Discussion:
Hey @karthickmuthuraj !

I do believe the attribute should be `default_action`, not `default action`. Does that work for you?
Yes, mistake at my end. it should be default_action.
Additional exception message,
I think the root cause is "[[]]" as a "re-direct" value. 

'default_action': [{'authenticate_cognito':[[]]},
                            'authenticate_oidc':[[]],
                            'fixed_response':[[]],
                            'forward:'[[]],
                            'order': [1],
                            'redirect':[[]],
                            'target_group_arn' " 
  

Resolving patch:
diff --git a/checkov/terraform/checks/resource/aws/AppLoadBalancerTLS12.py b/checkov/terraform/checks/resource/aws/AppLoadBalancerTLS12.py
--- a/checkov/terraform/checks/resource/aws/AppLoadBalancerTLS12.py
+++ b/checkov/terraform/checks/resource/aws/AppLoadBalancerTLS12.py
@@ -1,14 +1,16 @@
+from typing import Dict, List, Any
+
 from checkov.common.models.enums import CheckResult, CheckCategories
 from checkov.common.util.type_forcers import force_list
 from checkov.terraform.checks.resource.base_resource_check import BaseResourceCheck
 
 
 class AppLoadBalancerTLS12(BaseResourceCheck):
-    def __init__(self):
+    def __init__(self) -> None:
         name = "Ensure that load balancer is using TLS 1.2"
         id = "CKV_AWS_103"
-        supported_resources = ["aws_lb_listener", "aws_alb_listener"]
-        categories = [CheckCategories.GENERAL_SECURITY]
+        supported_resources = ("aws_lb_listener", "aws_alb_listener")
+        categories = (CheckCategories.GENERAL_SECURITY,)
         super().__init__(
             name=name,
             id=id,
@@ -16,7 +18,7 @@ def __init__(self):
             supported_resources=supported_resources,
         )
 
-    def scan_resource_conf(self, conf):
+    def scan_resource_conf(self, conf: Dict[str, List[Any]]) -> CheckResult:
         key = "protocol"
         self.evaluated_keys = [key]
         if key in conf.keys():
@@ -34,7 +36,7 @@ def scan_resource_conf(self, conf):
             for idx_action, action in enumerate(conf.get("default_action", [])):
                 redirects = action.get("redirect", [])
                 for idx_redirect, redirect in enumerate(force_list(redirects)):
-                    if redirect.get("protocol", []) == ["HTTPS"]:
+                    if isinstance(redirect, dict) and redirect.get("protocol", []) == ["HTTPS"]:
                         redirect_index = f"[{idx_redirect}]/" if isinstance(redirects, list) else ""
                         self.evaluated_keys.append(f'default_action/[{idx_action}]/redirect/{redirect_index}protocol')
                         return CheckResult.PASSED


Test patch:
diff --git a/tests/terraform/checks/resource/aws/example_AppLoadBalancerTLS12/main.tf b/tests/terraform/checks/resource/aws/example_AppLoadBalancerTLS12/main.tf
--- a/tests/terraform/checks/resource/aws/example_AppLoadBalancerTLS12/main.tf
+++ b/tests/terraform/checks/resource/aws/example_AppLoadBalancerTLS12/main.tf
@@ -138,4 +138,19 @@ resource "aws_alb_listener" "tls_fs_1_1" {
     type             = "forward"
     target_group_arn = var.aws_lb_target_group_arn
   }
-}
\ No newline at end of file
+}
+
+# mimicking a Terraform plan output by using an empty block
+
+resource "aws_lb_listener" "cognito" {
+  load_balancer_arn = var.aws_lb_arn
+  protocol          = "HTTP"
+  port              = "80"
+
+  default_action {
+    type = "authenticate-cognito"
+
+    redirect {
+    }
+  }
+}
diff --git a/tests/terraform/checks/resource/aws/test_AppLoadBalancerTLS12.py b/tests/terraform/checks/resource/aws/test_AppLoadBalancerTLS12.py
--- a/tests/terraform/checks/resource/aws/test_AppLoadBalancerTLS12.py
+++ b/tests/terraform/checks/resource/aws/test_AppLoadBalancerTLS12.py
@@ -31,13 +31,14 @@ def test(self):
             "aws_lb_listener.https_2016",
             "aws_lb_listener.tls_fs_1_1",
             "aws_alb_listener.tls_fs_1_1",
+            "aws_lb_listener.cognito",
         }
 
         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"], 7)
-        self.assertEqual(summary["failed"], 4)
+        self.assertEqual(summary["failed"], 5)
         self.assertEqual(summary["skipped"], 0)
         self.assertEqual(summary["parsing_errors"], 0)