diff --git a/checkov/terraform/checks/provider/__init__.py b/checkov/terraform/checks/provider/__init__.py index 798e90afcd..56037750d2 100644 --- a/checkov/terraform/checks/provider/__init__.py +++ b/checkov/terraform/checks/provider/__init__.py @@ -1,6 +1,7 @@ from checkov.terraform.checks.provider.aws import * # noqa -from checkov.terraform.checks.provider.linode import * # noqa +from checkov.terraform.checks.provider.awscc import * # noqa from checkov.terraform.checks.provider.bridgecrew import * # noqa +from checkov.terraform.checks.provider.linode import * # noqa from checkov.terraform.checks.provider.oci import * # noqa from checkov.terraform.checks.provider.openstack import * # noqa from checkov.terraform.checks.provider.panos import * # noqa diff --git a/checkov/terraform/checks/provider/awscc/__init__.py b/checkov/terraform/checks/provider/awscc/__init__.py new file mode 100644 index 0000000000..c619945591 --- /dev/null +++ b/checkov/terraform/checks/provider/awscc/__init__.py @@ -0,0 +1,5 @@ +from os.path import dirname, basename, isfile, join +import glob + +modules = glob.glob(join(dirname(__file__), "*.py")) +__all__ = [basename(f)[:-3] for f in modules if isfile(f) and not f.endswith("__init__.py")] diff --git a/checkov/terraform/checks/provider/awscc/credentials.py b/checkov/terraform/checks/provider/awscc/credentials.py new file mode 100644 index 0000000000..0feedb9901 --- /dev/null +++ b/checkov/terraform/checks/provider/awscc/credentials.py @@ -0,0 +1,37 @@ +import re +from typing import Any, Dict, List + +from checkov.common.models.consts import access_key_pattern, secret_key_pattern +from checkov.common.models.enums import CheckCategories, CheckResult +from checkov.terraform.checks.provider.base_check import BaseProviderCheck + + +class AWSCCCredentials(BaseProviderCheck): + def __init__(self) -> None: + name = "Ensure no hard coded AWS access key and secret key exists in provider" + id = "CKV_AWS_41" + supported_provider = ["awscc"] + categories = [CheckCategories.SECRETS] + super().__init__(name=name, id=id, categories=categories, supported_provider=supported_provider) + + def scan_provider_conf(self, conf: Dict[str, List[Any]]) -> CheckResult: + """ + see: https://registry.terraform.io/providers/hashicorp/awscc/latest/docs#authentication + """ + result = CheckResult.PASSED + if self.secret_found(conf, "access_key", access_key_pattern): + result = CheckResult.FAILED + if self.secret_found(conf, "secret_key", secret_key_pattern): + result = CheckResult.FAILED + return result + + def secret_found(self, conf: Dict[str, List[Any]], field: str, pattern: str) -> bool: + if field in conf.keys(): + value = conf[field][0] + if isinstance(value, str) and re.match(pattern, value) is not None: + conf[f'{self.id}_secret_{field}'] = value + return True + return False + + +check = AWSCCCredentials() diff --git a/tests/terraform/checks/provider/awscc/__init__.py b/tests/terraform/checks/provider/awscc/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/tests/terraform/checks/provider/awscc/example_Credentials/main.tf b/tests/terraform/checks/provider/awscc/example_Credentials/main.tf new file mode 100644 index 0000000000..41bf7fd487 --- /dev/null +++ b/tests/terraform/checks/provider/awscc/example_Credentials/main.tf @@ -0,0 +1,23 @@ +provider "awscc" { + alias = "pass" + region = "us-west-2" +} + +provider "awscc" { + alias = "fail" + region = "us-west-2" + access_key = "AKIAIOSFODNN7EXAMPLE" + secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" +} + +provider "awscc" { + alias = "fail2" + region = "us-west-2" + access_key = "AKIAIOSFODNN7EXAMPLE" +} + +provider "awscc" { + alias = "fail3" + region = "us-west-2" + secret_key = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" +} \ No newline at end of file diff --git a/tests/terraform/checks/provider/awscc/test_credentials.py b/tests/terraform/checks/provider/awscc/test_credentials.py new file mode 100644 index 0000000000..164ecebf0d --- /dev/null +++ b/tests/terraform/checks/provider/awscc/test_credentials.py @@ -0,0 +1,40 @@ +import os +import unittest + +from checkov.runner_filter import RunnerFilter +from checkov.terraform.checks.provider.awscc.credentials import check +from checkov.terraform.runner import Runner + + +class TestAWSCCCredentials(unittest.TestCase): + def test(self): + runner = Runner() + current_dir = os.path.dirname(os.path.realpath(__file__)) + + test_files_dir = current_dir + "/example_Credentials" + report = runner.run(root_folder=test_files_dir, runner_filter=RunnerFilter(checks=[check.id])) + summary = report.get_summary() + + passing_resources = { + "provider.awscc.pass" + } + failing_resources = { + "provider.awscc.fail", + "provider.awscc.fail2", + "provider.awscc.fail3", + } + + 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"], len(passing_resources)) + self.assertEqual(summary["failed"], len(failing_resources)) + self.assertEqual(summary["skipped"], 0) + self.assertEqual(summary["parsing_errors"], 0) + + self.assertEqual(passing_resources, passed_check_resources) + self.assertEqual(failing_resources, failed_check_resources) + + +if __name__ == "__main__": + unittest.main()