Repository: bridgecrewio/checkov

Issue:
Cloudformation NLB Listener Rules are incorrectly detected as ALB rules and fail the HTTPS expectation
**Describe the bug**
NLB listeners are evaluated as ALB listeners, and fail because they don't use HTTPS

**To Reproduce**
1. Create a Cloudformation template with NLB listeners (e.g. TCP)
2. Run default tests
3. Tests will fail with `"AWS::ElasticLoadBalancingV2::Listener.<listenername>\" failed in check \"Ensure ALB protocol is HTTPS\"

**Expected behavior**
NLB rules should pass. 

**Screenshots**


**Desktop (please complete the following information):**
 - OS: Ubuntu 20.04
 - Checkov Version: 1.0.423

**Additional context**
This resource:
```
    "ConsulDnsListener": {                                          
      "Type": "AWS::ElasticLoadBalancingV2::Listener",              
      "Properties": {                                               
        "DefaultActions": [                                         
          {                                                         
            "TargetGroupArn": {                                     
              "Ref": "ConsulDnsTargetGroup"                         
            },                                                      
            "Type": "forward"                                       
          }                                                         
        ],                                                          
        "LoadBalancerArn": {                                        
          "Ref": "LoadBalancerArn"                                  
        },                                                          
        "Port": 53,                                                 
        "Protocol": "TCP_UDP"                                       
      }                                                             
    },     
```
Produces this error:
```
{
  "type": "failure",
  "message": "Resource \"AWS::ElasticLoadBalancingV2::Listener.ConsulDnsListener\" failed in check \"Ensure ALB protocol is HTTPS\""
}```

Discussion:
schosterbarak: super! 
thanks @jdheyburn 

Patch:
diff --git a/checkov/cloudformation/checks/resource/aws/ALBListenerHTTPS.py b/checkov/cloudformation/checks/resource/aws/ALBListenerHTTPS.py
index a26144506..1034c9cfe 100644
--- a/checkov/cloudformation/checks/resource/aws/ALBListenerHTTPS.py
+++ b/checkov/cloudformation/checks/resource/aws/ALBListenerHTTPS.py
@@ -20,7 +20,7 @@ class ALBListenerHTTPS(BaseResourceCheck):
 
         if 'Properties' in conf.keys():
             if 'Protocol' in conf['Properties'].keys():
-                if conf['Properties']['Protocol'] in ('HTTPS', 'TLS'):
+                if conf['Properties']['Protocol'] in ('HTTPS', 'TLS', 'TCP', 'UDP', 'TCP_UDP'):
                     return CheckResult.PASSED
                 else:
                     if (
diff --git a/checkov/terraform/checks/resource/aws/ALBListenerHTTPS.py b/checkov/terraform/checks/resource/aws/ALBListenerHTTPS.py
index 1399252ce..479e57e2f 100644
--- a/checkov/terraform/checks/resource/aws/ALBListenerHTTPS.py
+++ b/checkov/terraform/checks/resource/aws/ALBListenerHTTPS.py
@@ -19,11 +19,7 @@ class ALBListenerHTTPS(BaseResourceCheck):
         """
         key = 'protocol'
         if key in conf.keys():
-            if (
-                conf[key] == ["HTTPS"]
-                or
-                conf[key] == ["TLS"]
-            ):
+            if conf[key] in (["HTTPS"], ["TLS"], ["TCP"], ["UDP"], ["TCP_UDP"]):
                 return CheckResult.PASSED
             elif conf[key] == ["HTTP"]:
                 if 'default_action' in conf.keys():


Test patch:
diff --git a/tests/cloudformation/checks/resource/aws/example_ALBListener/ALBListenerHTTPS-PASSED-TCP.yaml b/tests/cloudformation/checks/resource/aws/example_ALBListener/ALBListenerHTTPS-PASSED-TCP.yaml
new file mode 100644
index 000000000..3cff7f613
--- /dev/null
+++ b/tests/cloudformation/checks/resource/aws/example_ALBListener/ALBListenerHTTPS-PASSED-TCP.yaml
@@ -0,0 +1,67 @@
+Description: >
+  This template deploys an NLB with TLS termination
+Parameters:
+  VPC:
+    Type: AWS::EC2::VPC::Id
+    Description: Choose which VPC the Application Load Balancer should be deployed to
+
+  Subnets:
+    Description: Choose a minimum of 2 subnets the ALB should be deployed to
+    Type: List<AWS::EC2::Subnet::Id>
+
+Resources:
+  LoadBalancer:
+    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
+    Properties:
+      Name: CheckovTest
+      Type: 'network'
+      Subnets: !Ref Subnets
+  
+  ListenerHTTPS:
+    Type: AWS::ElasticLoadBalancingV2::Listener
+    Properties:
+      Certificates:
+        - CertificateArn: !Ref Certificate
+      LoadBalancerArn: !Ref LoadBalancer
+      Port: 22
+      Protocol: TCP
+      DefaultActions:
+        - Type: forward
+          TargetGroupArn: !Ref DefaultTargetGroup
+
+  ### NOTE - Stack will remain in CREATE_IN_PROGRESS until you validate the certificate!
+  Certificate:
+    Type: AWS::CertificateManager::Certificate
+    Properties:
+      DomainName: example.com
+      DomainValidationOptions:
+        - DomainName: example.com
+          ValidationDomain: example.com
+
+  ListenerCert:
+    Type: AWS::ElasticLoadBalancingV2::ListenerCertificate
+    Properties: 
+      Certificates: 
+        - CertificateArn: !Ref Certificate
+      ListenerArn: !Ref ListenerHTTPS
+
+  # We define a default target group here, as this is a mandatory Parameters
+  # when creating an Application Load Balancer Listener. This is not used, instead
+  # a target group is created per-service in each service template (../services/*)
+  DefaultTargetGroup:
+    Type: AWS::ElasticLoadBalancingV2::TargetGroup
+    Properties:
+      Name: checkov-default
+      VpcId: !Ref VPC
+      Port: 22
+      Protocol: TCP
+
+Outputs:
+  LoadBalancer:
+    Description: A reference to the Application Load Balancer
+    Value: !Ref LoadBalancer
+
+  LoadBalancerUrl:
+    Description: The URL of the ALB
+    Value: !GetAtt LoadBalancer.DNSName
+
diff --git a/tests/cloudformation/checks/resource/aws/example_ALBListener/ALBListenerHTTPS-PASSED-TCP_UDP.yaml b/tests/cloudformation/checks/resource/aws/example_ALBListener/ALBListenerHTTPS-PASSED-TCP_UDP.yaml
new file mode 100644
index 000000000..5d33b7b29
--- /dev/null
+++ b/tests/cloudformation/checks/resource/aws/example_ALBListener/ALBListenerHTTPS-PASSED-TCP_UDP.yaml
@@ -0,0 +1,67 @@
+Description: >
+  This template deploys an NLB with TLS termination
+Parameters:
+  VPC:
+    Type: AWS::EC2::VPC::Id
+    Description: Choose which VPC the Application Load Balancer should be deployed to
+
+  Subnets:
+    Description: Choose a minimum of 2 subnets the ALB should be deployed to
+    Type: List<AWS::EC2::Subnet::Id>
+
+Resources:
+  LoadBalancer:
+    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
+    Properties:
+      Name: CheckovTest
+      Type: 'network'
+      Subnets: !Ref Subnets
+  
+  ListenerHTTPS:
+    Type: AWS::ElasticLoadBalancingV2::Listener
+    Properties:
+      Certificates:
+        - CertificateArn: !Ref Certificate
+      LoadBalancerArn: !Ref LoadBalancer
+      Port: 53
+      Protocol: TCP_UDP
+      DefaultActions:
+        - Type: forward
+          TargetGroupArn: !Ref DefaultTargetGroup
+
+  ### NOTE - Stack will remain in CREATE_IN_PROGRESS until you validate the certificate!
+  Certificate:
+    Type: AWS::CertificateManager::Certificate
+    Properties:
+      DomainName: example.com
+      DomainValidationOptions:
+        - DomainName: example.com
+          ValidationDomain: example.com
+
+  ListenerCert:
+    Type: AWS::ElasticLoadBalancingV2::ListenerCertificate
+    Properties: 
+      Certificates: 
+        - CertificateArn: !Ref Certificate
+      ListenerArn: !Ref ListenerHTTPS
+
+  # We define a default target group here, as this is a mandatory Parameters
+  # when creating an Application Load Balancer Listener. This is not used, instead
+  # a target group is created per-service in each service template (../services/*)
+  DefaultTargetGroup:
+    Type: AWS::ElasticLoadBalancingV2::TargetGroup
+    Properties:
+      Name: checkov-default
+      VpcId: !Ref VPC
+      Port: 53
+      Protocol: TCP_UDP
+
+Outputs:
+  LoadBalancer:
+    Description: A reference to the Application Load Balancer
+    Value: !Ref LoadBalancer
+
+  LoadBalancerUrl:
+    Description: The URL of the ALB
+    Value: !GetAtt LoadBalancer.DNSName
+
diff --git a/tests/cloudformation/checks/resource/aws/example_ALBListener/ALBListenerHTTPS-PASSED-UDP.yaml b/tests/cloudformation/checks/resource/aws/example_ALBListener/ALBListenerHTTPS-PASSED-UDP.yaml
new file mode 100644
index 000000000..94c5322cc
--- /dev/null
+++ b/tests/cloudformation/checks/resource/aws/example_ALBListener/ALBListenerHTTPS-PASSED-UDP.yaml
@@ -0,0 +1,67 @@
+Description: >
+  This template deploys an NLB with TLS termination
+Parameters:
+  VPC:
+    Type: AWS::EC2::VPC::Id
+    Description: Choose which VPC the Application Load Balancer should be deployed to
+
+  Subnets:
+    Description: Choose a minimum of 2 subnets the ALB should be deployed to
+    Type: List<AWS::EC2::Subnet::Id>
+
+Resources:
+  LoadBalancer:
+    Type: AWS::ElasticLoadBalancingV2::LoadBalancer
+    Properties:
+      Name: CheckovTest
+      Type: 'network'
+      Subnets: !Ref Subnets
+  
+  ListenerHTTPS:
+    Type: AWS::ElasticLoadBalancingV2::Listener
+    Properties:
+      Certificates:
+        - CertificateArn: !Ref Certificate
+      LoadBalancerArn: !Ref LoadBalancer
+      Port: 53
+      Protocol: UDP
+      DefaultActions:
+        - Type: forward
+          TargetGroupArn: !Ref DefaultTargetGroup
+
+  ### NOTE - Stack will remain in CREATE_IN_PROGRESS until you validate the certificate!
+  Certificate:
+    Type: AWS::CertificateManager::Certificate
+    Properties:
+      DomainName: example.com
+      DomainValidationOptions:
+        - DomainName: example.com
+          ValidationDomain: example.com
+
+  ListenerCert:
+    Type: AWS::ElasticLoadBalancingV2::ListenerCertificate
+    Properties: 
+      Certificates: 
+        - CertificateArn: !Ref Certificate
+      ListenerArn: !Ref ListenerHTTPS
+
+  # We define a default target group here, as this is a mandatory Parameters
+  # when creating an Application Load Balancer Listener. This is not used, instead
+  # a target group is created per-service in each service template (../services/*)
+  DefaultTargetGroup:
+    Type: AWS::ElasticLoadBalancingV2::TargetGroup
+    Properties:
+      Name: checkov-default
+      VpcId: !Ref VPC
+      Port: 53
+      Protocol: UDP
+
+Outputs:
+  LoadBalancer:
+    Description: A reference to the Application Load Balancer
+    Value: !Ref LoadBalancer
+
+  LoadBalancerUrl:
+    Description: The URL of the ALB
+    Value: !GetAtt LoadBalancer.DNSName
+
diff --git a/tests/cloudformation/checks/resource/aws/test_ALBListenerHTTPS.py b/tests/cloudformation/checks/resource/aws/test_ALBListenerHTTPS.py
index d3d6b3ca3..0165fe463 100644
--- a/tests/cloudformation/checks/resource/aws/test_ALBListenerHTTPS.py
+++ b/tests/cloudformation/checks/resource/aws/test_ALBListenerHTTPS.py
@@ -16,7 +16,7 @@ class TestALBListenerHTTPS(unittest.TestCase):
         report = runner.run(root_folder=test_files_dir,runner_filter=RunnerFilter(checks=[check.id]))
         summary = report.get_summary()
 
-        self.assertEqual(summary['passed'], 4)
+        self.assertEqual(summary['passed'], 7)
         self.assertEqual(summary['failed'], 1)
         self.assertEqual(summary['skipped'], 0)
         self.assertEqual(summary['parsing_errors'], 0)
diff --git a/tests/terraform/checks/resource/aws/test_ALBListenerHTTPS.py b/tests/terraform/checks/resource/aws/test_ALBListenerHTTPS.py
index 6c1d32bff..5364f42d5 100644
--- a/tests/terraform/checks/resource/aws/test_ALBListenerHTTPS.py
+++ b/tests/terraform/checks/resource/aws/test_ALBListenerHTTPS.py
@@ -20,6 +20,24 @@ class TestALBListenerHTTPS(unittest.TestCase):
         scan_result = check.scan_resource_conf(conf=resource_conf)
         self.assertEqual(CheckResult.PASSED, scan_result)
 
+    def test_nlb_tcp_success(self):
+        resource_conf = {'load_balancer_arn': ['${aws_lb.front_end.arn}'], 'port': ['22'], 'protocol': ['TCP']}
+
+        scan_result = check.scan_resource_conf(conf=resource_conf)
+        self.assertEqual(CheckResult.PASSED, scan_result)
+
+    def test_nlb_udp_success(self):
+        resource_conf = {'load_balancer_arn': ['${aws_lb.front_end.arn}'], 'port': ['53'], 'protocol': ['UDP']}
+
+        scan_result = check.scan_resource_conf(conf=resource_conf)
+        self.assertEqual(CheckResult.PASSED, scan_result)
+
+    def test_nlb_tcp_udp_success(self):
+        resource_conf = {'load_balancer_arn': ['${aws_lb.front_end.arn}'], 'port': ['53'], 'protocol': ['TCP_UDP']}
+
+        scan_result = check.scan_resource_conf(conf=resource_conf)
+        self.assertEqual(CheckResult.PASSED, scan_result)
+
     def test_failure(self):
         resource_conf = {'load_balancer_arn': ['${aws_lb.front_end.arn}'], 'port': ['80'], 'protocol': ['HTTP']}
         scan_result = check.scan_resource_conf(conf=resource_conf)