Repository: bridgecrewio/checkov

Issue:
False positive on CKV_AWS_59 - APIGatewayAuthorization ignores API keys
**Describe the bug**
**CKV_AWS_59** assumes the API is open to the public if authorization is **NONE**. However, API keys are another option on REST APIs and are configured separately. See https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-setup-api-key-with-console.html.

**To Reproduce**
The following terraform code will cause a test failure, which appears to be against the spirit of the rule:
```terraform
resource "aws_api_gateway_method" "POST" {
...
authorization = NONE
api_key_required = true
...
}
````

**Expected behavior**
I would expect this configuration to be considered secure. 

**Desktop (please complete the following information):**
 - OS: linux/amd64 Docker image bridgecrew/checkov:1.0.833
 - Checkov Version 1.0.833





Discussion:
Hi @ketumbra , I agree.
Seems like an easy fix at: https://github.com/bridgecrewio/checkov/blob/1da8a1d88f4100075f066115ac995497b3720834/checkov/terraform/checks/resource/aws/APIGatewayAuthorization.py#L14

and additional test at:
https://github.com/bridgecrewio/checkov/blob/82d707d52f3cfc870c7b9c79229a96cf77d5abd8/tests/terraform/checks/resource/aws/test_APIGatewayAuthorization.py

would you like to give it a try and contribute it ?
Sure. Here goes.

Resolving patch:
diff --git a/checkov/cloudformation/checks/resource/aws/APIGatewayAuthorization.py b/checkov/cloudformation/checks/resource/aws/APIGatewayAuthorization.py
--- a/checkov/cloudformation/checks/resource/aws/APIGatewayAuthorization.py
+++ b/checkov/cloudformation/checks/resource/aws/APIGatewayAuthorization.py
@@ -14,7 +14,8 @@ def scan_resource_conf(self, conf):
         if 'Properties' in conf.keys():
             if 'HttpMethod' in conf['Properties'].keys() and 'AuthorizationType' in conf['Properties'].keys():
                 if conf['Properties']['HttpMethod'] != "OPTIONS" and conf['Properties']['AuthorizationType'] == "NONE":
-                    return CheckResult.FAILED
+                    if 'ApiKeyRequired' not in conf['Properties'].keys() or conf['Properties']['ApiKeyRequired'] == False:
+                        return CheckResult.FAILED
         return CheckResult.PASSED
 
 check = APIGatewayAuthorization()
diff --git a/checkov/terraform/checks/resource/aws/APIGatewayAuthorization.py b/checkov/terraform/checks/resource/aws/APIGatewayAuthorization.py
--- a/checkov/terraform/checks/resource/aws/APIGatewayAuthorization.py
+++ b/checkov/terraform/checks/resource/aws/APIGatewayAuthorization.py
@@ -12,8 +12,8 @@ def __init__(self):
         super().__init__(name=name, id=id, categories=categories, supported_resources=supported_resources)
 
     def scan_resource_conf(self, conf):
-        self.evaluated_keys = ['http_method', 'authorization']
-        if conf['http_method'][0] != "OPTIONS" and conf['authorization'][0] == "NONE":
+        self.evaluated_keys = ['http_method', 'authorization', 'api_key_required']
+        if conf['http_method'][0] != "OPTIONS" and conf['authorization'][0] == "NONE" and ('api_key_required' not in conf or conf['api_key_required'][0] == False):
             return CheckResult.FAILED
         return CheckResult.PASSED
 


Test patch:
diff --git a/tests/cloudformation/checks/resource/aws/example_APIGatewayAuthorization/APIGatewayAuthorization-FAILED.yaml b/tests/cloudformation/checks/resource/aws/example_APIGatewayAuthorization/APIGatewayAuthorization-FAILED.yaml
--- a/tests/cloudformation/checks/resource/aws/example_APIGatewayAuthorization/APIGatewayAuthorization-FAILED.yaml
+++ b/tests/cloudformation/checks/resource/aws/example_APIGatewayAuthorization/APIGatewayAuthorization-FAILED.yaml
@@ -14,3 +14,4 @@ Resources:
       ResourceId: MyResourceID 
       HttpMethod: POST
       AuthorizationType: NONE
+      ApiKeyRequired: false
diff --git a/tests/cloudformation/checks/resource/aws/example_APIGatewayAuthorization/APIGatewayAuthorization-PASSED.yaml b/tests/cloudformation/checks/resource/aws/example_APIGatewayAuthorization/APIGatewayAuthorization-PASSED.yaml
--- a/tests/cloudformation/checks/resource/aws/example_APIGatewayAuthorization/APIGatewayAuthorization-PASSED.yaml
+++ b/tests/cloudformation/checks/resource/aws/example_APIGatewayAuthorization/APIGatewayAuthorization-PASSED.yaml
@@ -22,3 +22,11 @@ Resources:
       HttpMethod: GET
       AuthorizationType: CUSTOM
       AuthorizerId: MyAuthorizerID
+  MyMethod3:
+    Type: 'AWS::ApiGateway::Method'
+    Properties:
+      RestApiId: MyAPIID
+      ResourceId: MyResourceID 
+      HttpMethod: GET
+      AuthorizationType: NONE
+      ApiKeyRequired: true
diff --git a/tests/cloudformation/checks/resource/aws/test_APIGatewayAuthorization.py b/tests/cloudformation/checks/resource/aws/test_APIGatewayAuthorization.py
--- a/tests/cloudformation/checks/resource/aws/test_APIGatewayAuthorization.py
+++ b/tests/cloudformation/checks/resource/aws/test_APIGatewayAuthorization.py
@@ -16,7 +16,7 @@ def test_summary(self):
         report = runner.run(root_folder=test_files_dir,runner_filter=RunnerFilter(checks=[check.id]))
         summary = report.get_summary()
 
-        self.assertEqual(summary['passed'], 3)
+        self.assertEqual(summary['passed'], 4)
         self.assertEqual(summary['failed'], 2)
         self.assertEqual(summary['skipped'], 0)
         self.assertEqual(summary['parsing_errors'], 0)
diff --git a/tests/terraform/checks/resource/aws/test_APIGatewayAuthorization.py b/tests/terraform/checks/resource/aws/test_APIGatewayAuthorization.py
--- a/tests/terraform/checks/resource/aws/test_APIGatewayAuthorization.py
+++ b/tests/terraform/checks/resource/aws/test_APIGatewayAuthorization.py
@@ -23,6 +23,15 @@ def test_success(self):
         scan_result = check.scan_resource_conf(conf=resource_conf)
         self.assertEqual(CheckResult.PASSED, scan_result)
 
+    def test_success_apikey(self):
+        resource_conf = {"rest_api_id": ["${var.rest_api_id}"],
+                         "resource_id": ["${var.resource_id}"],
+                         "http_method": ["${var.method}"],
+                         "authorization": ["NONE"],
+                         "api_key_required": [True]}
+        scan_result = check.scan_resource_conf(conf=resource_conf)
+        self.assertEqual(CheckResult.PASSED, scan_result)
+
 
 if __name__ == '__main__':
     unittest.main()