def test_registry_load(self): registry = Registry( parser=NXGraphCheckParser(), checks_dir=str( Path(__file__).parent.parent.parent.parent.parent / "checkov" / "terraform" / "checks" / "graph_checks")) registry.load_checks() self.assertGreater(len(registry.checks), 0)
def get_graph_checks_registry(check_type): if not _registry_instances.get(check_type): _registry_instances[check_type] = Registry( parser=NXGraphCheckParser(), checks_dir= f"{Path(__file__).parent.parent.parent}/{check_type}/checks/graph_checks" ) return _registry_instances[check_type]
def test_internal_graph_checks_load(self): registry = Registry( parser=NXGraphCheckParser(), checks_dir=str( Path(__file__).parent.parent.parent.parent / "checkov" / "terraform" / "checks" / "graph_checks")) registry.load_checks() runner_filter = RunnerFilter() for check in registry.checks: self.assertFalse(runner_filter.is_external_check(check))
def test_non_colliding_graph_check_ids(self): check_id_check_class_map = {} graph_registry = Registry( parser=NXGraphCheckParser(), checks_dir=str( Path(__file__).parent.parent.parent / "checkov" / "terraform" / "checks" / "graph_checks")) graph_registry.load_checks() for check in graph_registry.checks: check_id_check_class_map.setdefault(check.id, []).append(check) for check_id, check_classes in check_id_check_class_map.items(): self.assertEqual(len(set(check_classes)), 1, "collision on check_id={}".format(check_id))
class CustomPoliciesIntegration(BaseIntegrationFeature): def __init__(self, bc_integration): super().__init__(bc_integration, order=0) self.policies = {} self.platform_policy_parser = NXGraphCheckParser() def is_valid(self): return self.bc_integration.is_integration_configured() and not self.bc_integration.skip_policy_download def pre_scan(self): self.policies = self._get_policies_from_platform() for policy in self.policies: converted_check = self._convert_raw_check(policy) resource_types = Registry._get_resource_types(converted_check['metadata']) check = self.platform_policy_parser.parse_raw_check(converted_check, resources_types=resource_types) graph_registry.checks.append(check) logging.debug(f'Found {len(self.policies)} custom policies from the platform.') @staticmethod def _convert_raw_check(policy): metadata = { 'id': policy['id'], 'name': policy['title'], 'category': policy['category'], 'scope': { 'provider': policy['provider'] } } check = { 'metadata': metadata, 'definition': policy['conditionQuery'] } return check def _get_policies_from_platform(self): headers = merge_dicts(get_default_get_headers(self.bc_integration.bc_source, self.bc_integration.bc_source_version), get_auth_header(self.bc_integration.bc_api_key)) response = requests.request('GET', self.policies_url, headers=headers) if response.status_code != 200: error_message = extract_error_message(response) raise Exception(f'Get custom policies request failed with response code {response.status_code}: {error_message}') policies = response.json().get('data', []) return policies
class CustomPoliciesIntegration(BaseIntegrationFeature): def __init__(self, bc_integration): super().__init__(bc_integration, order=0) self.policies = {} self.platform_policy_parser = NXGraphCheckParser() self.policies_url = f"{self.bc_integration.api_url}/api/v1/policies/table/data" self.bc_cloned_checks: Dict[str, List[dict]] = defaultdict(list) def is_valid(self) -> bool: return ( self.bc_integration.is_integration_configured() and not self.bc_integration.skip_policy_download and not self.integration_feature_failures ) def pre_scan(self): try: self.policies = self._get_policies_from_platform() for policy in self.policies: converted_check = self._convert_raw_check(policy) source_incident_id = policy.get('sourceIncidentId') if source_incident_id: self.bc_cloned_checks[source_incident_id].append(policy) continue resource_types = Registry._get_resource_types(converted_check['metadata']) check = self.platform_policy_parser.parse_raw_check(converted_check, resources_types=resource_types) if re.match(CFN_RESOURCE_TYPE_IDENTIFIER, check.resource_types[0]): get_graph_checks_registry("cloudformation").checks.append(check) else: get_graph_checks_registry("terraform").checks.append(check) logging.debug(f'Found {len(self.policies)} custom policies from the platform.') except Exception as e: self.integration_feature_failures = True logging.debug(f'{e} \nScanning without applying custom policies from the platform.', exc_info=True) @staticmethod def _convert_raw_check(policy): metadata = { 'id': policy['id'], 'name': policy['title'], 'category': policy['category'], 'scope': { 'provider': policy['provider'] } } check = { 'metadata': metadata, 'definition': policy['conditionQuery'] } return check def _get_policies_from_platform(self): headers = merge_dicts(get_default_get_headers(self.bc_integration.bc_source, self.bc_integration.bc_source_version), get_auth_header(self.bc_integration.get_auth_token())) response = requests.request('GET', self.policies_url, headers=headers) if response.status_code != 200: error_message = extract_error_message(response) raise Exception(f'Get custom policies request failed with response code {response.status_code}: {error_message}') policies = response.json().get('data', []) policies = [p for p in policies if p['isCustom']] return policies def post_runner(self, scan_reports): if self.bc_cloned_checks: scan_reports.failed_checks = self.extend_records_with_cloned_policies(scan_reports.failed_checks) scan_reports.passed_checks = self.extend_records_with_cloned_policies(scan_reports.passed_checks) scan_reports.skipped_checks = self.extend_records_with_cloned_policies(scan_reports.skipped_checks) def extend_records_with_cloned_policies(self, records): bc_check_ids = [record.bc_check_id for record in records] for idx, bc_check_id in enumerate(bc_check_ids): cloned_policies = self.bc_cloned_checks.get(bc_check_id, []) for cloned_policy in cloned_policies: new_record = deepcopy(records[idx]) new_record.check_id = cloned_policy['id'] new_record.bc_check_id = cloned_policy['id'] new_record.guideline = cloned_policy['guideline'] new_record.severity = cloned_policy['severity'] new_record.check_name = cloned_policy['title'] records.append(new_record) return records
def get_checks_registry(self): registry = Registry(parser=NXGraphCheckParser(), checks_dir=self.real_graph_checks_path) registry.load_checks() registry.load_external_checks(self.checks_dir) return registry
def __init__(self, bc_integration): super().__init__(bc_integration, order=0) self.policies = {} self.platform_policy_parser = NXGraphCheckParser() self.policies_url = f"{self.bc_integration.api_url}/api/v1/policies/table/data"
class CustomPoliciesIntegration(BaseIntegrationFeature): def __init__(self, bc_integration): super().__init__(bc_integration, order=0) self.policies = {} self.platform_policy_parser = NXGraphCheckParser() self.policies_url = f"{self.bc_integration.api_url}/api/v1/policies/table/data" def is_valid(self): return self.bc_integration.is_integration_configured() and not self.bc_integration.skip_policy_download \ and not self.integration_feature_failures def pre_scan(self): try: self.policies = self._get_policies_from_platform() for policy in self.policies: converted_check = self._convert_raw_check(policy) resource_types = Registry._get_resource_types( converted_check['metadata']) check = self.platform_policy_parser.parse_raw_check( converted_check, resources_types=resource_types) if re.match(CFN_RESOURCE_TYPE_IDENTIFIER, check.resource_types[0]): get_graph_checks_registry("cloudformation").checks.append( check) else: get_graph_checks_registry("terraform").checks.append(check) logging.debug( f'Found {len(self.policies)} custom policies from the platform.' ) except Exception as e: self.integration_feature_failures = True logging.debug( f'{e} \nScanning without applying custom policies from the platform.', exc_info=True) @staticmethod def _convert_raw_check(policy): metadata = { 'id': policy['id'], 'name': policy['title'], 'category': policy['category'], 'scope': { 'provider': policy['provider'] } } check = {'metadata': metadata, 'definition': policy['conditionQuery']} return check def _get_policies_from_platform(self): headers = merge_dicts( get_default_get_headers(self.bc_integration.bc_source, self.bc_integration.bc_source_version), get_auth_header(self.bc_integration.bc_api_key)) response = requests.request('GET', self.policies_url, headers=headers) if response.status_code != 200: error_message = extract_error_message(response) raise Exception( f'Get custom policies request failed with response code {response.status_code}: {error_message}' ) policies = response.json().get('data', []) policies = [p for p in policies if p['isCustom']] return policies
def setUp(self): self.source = "Terraform" self.registry = Registry(parser=NXGraphCheckParser(), checks_dir=self.checks_dir) self.registry.load_checks() self.runner = Runner(external_registries=[self.registry])
from checkov.common.checks_infra.registry import Registry from checkov.terraform.context_parsers.registry import parser_registry from checkov.terraform.evaluation.base_variable_evaluation import BaseVariableEvaluation from checkov.terraform.graph_builder.graph_components.attribute_names import CustomAttributes from checkov.terraform.graph_builder.graph_to_tf_definitions import convert_graph_vertices_to_tf_definitions from checkov.terraform.graph_builder.local_graph import LocalGraph from checkov.terraform.graph_manager import GraphManager # Allow the evaluation of empty variables from checkov.terraform.parser import Parser from checkov.terraform.tag_providers import get_resource_tags dpath.options.ALLOW_EMPTY_STRING_KEYS = True CHECK_BLOCK_TYPES = frozenset(['resource', 'data', 'provider', 'module']) graph_registry = Registry(parser=NXGraphCheckParser(), checks_dir=str(Path(__file__).parent / "checks" / "graph_checks")) class Runner(BaseRunner): check_type = "terraform" def __init__(self, parser=Parser(), db_connector=NetworkxConnector(), external_registries=None, source="Terraform", graph_class=LocalGraph, graph_manager=None): self.external_registries = [] if external_registries is None else external_registries self.graph_class = graph_class self.parser = parser self.tf_definitions = None self.definitions_context = None self.breadcrumbs = None self.definitions_context = {} self.evaluations_context: Dict[str, Dict[str, EvaluationContext]] = {}
def test_policy_load(self): # response from API policies = [ { "provider": "AWS", "id": "mikepolicies_AWS_1625063607541", "title": "yaml1", "severity": "MEDIUM", "category": "General", "resourceTypes": [ "aws_s3_bucket" ], "accountsData": { "mikeurbanski1/terragoat3": { "amounts": { "CLOSED": 0, "DELETED": 0, "OPEN": 1, "REMEDIATED": 0, "SUPPRESSED": 0 }, "lastUpdateDate": "2021-06-30T14:33:54.638Z" } }, "guideline": "yaml1", "isCustom": True, "conditionQuery": { "or": [ { "value": "xyz", "operator": "equals", "attribute": "xyz", "cond_type": "attribute", "resource_types": [ "aws_s3_bucket" ] } ] }, "benchmarks": {}, "createdBy": "*****@*****.**", "code": "---\nmetadata:\n name: \"yaml1\" #give your custom policy a unique name \n guidelines: " "\"yaml1\" #add text that explains the configuration the policy looks for, its implications, " "and how to fix it\n category: \"general\" #choose one: " "\"general\"/\"elaticsearch\"/\"iam\"/\"kubernetes\"/\"logging\"/\"monitoring\"/\"networking" "\"/\"public\"/\"secrets\"/\"serverless\"/\"storage\"\n severity: \"medium\" #choose one: " "\"critical\"/\"high\"/\"medium\"/\"low\"/\"info\"\nscope:\n provider: \"aws\" #choose one: " "\"aws\"/\"azure\"/\"gcp\"\ndefinition: #define the conditions the policy searches for.\n " "or:\n - cond_type: \"attribute\"\n resource_types:\n - \"aws_s3_bucket\"\n " "attribute: \"xyz\"\n operator: \"equals\"\n value: \"xyz\"\n# - cond_type: " "\"attribute\"\n# resource_types:\n# - \"aws_instance\"\n# attribute: " "\"instance_type\"\n# operator: \"equals\"\n# value: \"t3.nano\"\n ", "sourceIncidentId": "" }, { "provider": "AWS", "id": "mikepolicies_aws_1625063842021", "title": "ui1", "severity": "HIGH", "category": "General", "resourceTypes": [ "aws_s3_bucket" ], "accountsData": { "mikeurbanski1/terragoat3": { "amounts": { "CLOSED": 0, "DELETED": 0, "OPEN": 1, "REMEDIATED": 0, "SUPPRESSED": 0 }, "lastUpdateDate": "2021-06-30T14:42:29.534Z" } }, "guideline": "ui1", "isCustom": True, "conditionQuery": { "value": "abc", "operator": "equals", "attribute": "region", "cond_type": "attribute", "resource_types": [ "aws_s3_bucket" ] }, "benchmarks": {}, "createdBy": "*****@*****.**", "code": None, "sourceIncidentId": "" }, { "provider": "AWS", "id": "kpande_AWS_1635180094606", "title": "Check that all EC2 instances are tagged with yor_trace", "descriptiveTitle": "null", "constructiveTitle": "null", "severity": "LOW", "pcSeverity": "null", "category": "General", "resourceTypes": [ "AWS::EC2::Instance" ], "guideline": "Check for YOR tagging", "isCustom": True, "conditionQuery": { "operator": "exists", "attribute": "Tags.yor_trace", "cond_type": "attribute", "resource_types": [ "AWS::EC2::Instance" ] }, "benchmarks": {}, "createdBy": "*****@*****.**", "code": "---\nmetadata:\n name: \"Check that all resources are tagged with the key - yor_trace\"\n " "guidelines: \"Check for YOR tagging\"\n category: \"general\"\n severity: \"low\"\nscope:\n " "provider: \"aws\"\ndefinition:\n cond_type: \"attribute\"\n resource_types: \n " " - \"AWS::EC2::Instance\"\n attribute: \"Tags.yor_trace\"\n operator: " "\"exists\"", "frameworks": [ "Terraform", "CloudFormation" ], "sourceIncidentId": "" }, { "provider": "AWS", "id": "kpande_AWS_1635187541652", "title": "Custom - ensure MSK Cluster logging is enabled", "descriptiveTitle": "null", "constructiveTitle": "null", "severity": "MEDIUM", "pcSeverity": "null", "category": "Logging", "resourceTypes": [ "AWS::MSK::Cluster" ], "accountsData": {}, "guideline": "Some sample guidelines", "isCustom": True, "conditionQuery": { "or": [ { "value": "true", "operator": "equals", "attribute": "LoggingInfo.BrokerLogs.S3.Enabled", "cond_type": "attribute", "resource_types": [ "AWS::MSK::Cluster" ] }, { "value": "true", "operator": "equals", "attribute": "LoggingInfo.BrokerLogs.Firehose.Enabled", "cond_type": "attribute", "resource_types": [ "AWS::MSK::Cluster" ] }, { "value": "true", "operator": "equals", "attribute": "LoggingInfo.BrokerLogs.CloudWatchLogs.Enabled", "cond_type": "attribute", "resource_types": [ "AWS::MSK::Cluster" ] } ] }, "benchmarks": {}, "createdBy": "*****@*****.**", "code": "---\nmetadata:\n name: \"Custom - ensure MSK Cluster logging is enabled\"\n category: " "\"logging\"\n severity: \"medium\"\n guidelines: \"Some sample guidelines\"\nscope:\n " "provider: \"aws\"\ndefinition:\n or:\n - cond_type: attribute\n attribute: " "LoggingInfo.BrokerLogs.S3.Enabled\n operator: equals\n value: \"true\"\n " "resource_types:\n - \"AWS::MSK::Cluster\"\n - cond_type: attribute\n " "attribute: LoggingInfo.BrokerLogs.Firehose.Enabled\n operator: equals\n value: " "\"true\"\n resource_types:\n - \"AWS::MSK::Cluster\"\n - cond_type: " "attribute\n attribute: LoggingInfo.BrokerLogs.CloudWatchLogs.Enabled\n operator: " "equals\n value: \"true\"\n resource_types:\n - \"AWS::MSK::Cluster\"", "frameworks": [ "Terraform", "CloudFormation" ], "sourceIncidentId": "" } ] # for this test, we simulate some of the check registry manipulation; otherwise the singleton # instance will be modified and break other tests. parser = NXGraphCheckParser() registry = Registry(parser=NXGraphCheckParser(), checks_dir=str( Path(__file__).parent.parent.parent.parent / "checkov" / "terraform" / "checks" / "graph_checks")) checks = [parser.parse_raw_check(CustomPoliciesIntegration._convert_raw_check(p)) for p in policies] registry.checks = checks # simulate that the policy downloader will do tf_runner = TerraformRunner(external_registries=[registry]) cfn_runner = CFNRunner(external_registries=[registry]) current_dir = os.path.dirname(os.path.realpath(__file__)) test_files_dir = current_dir + "/example_custom_policy_dir" report = tf_runner.run(root_folder=test_files_dir, runner_filter=RunnerFilter()) self.assertEqual(len([r for r in report.failed_checks if r.check_id == 'mikepolicies_aws_1625063842021']), 1) self.assertEqual(len([r for r in report.failed_checks if r.check_id == 'mikepolicies_AWS_1625063607541']), 1) report = tf_runner.run(root_folder=test_files_dir, runner_filter=RunnerFilter(checks=['mikepolicies_aws_1625063842021'])) self.assertEqual(len([r for r in report.failed_checks if r.check_id == 'mikepolicies_aws_1625063842021']), 1) self.assertEqual(len([r for r in report.failed_checks if r.check_id == 'mikepolicies_AWS_1625063607541']), 0) report = tf_runner.run(root_folder=test_files_dir, runner_filter=RunnerFilter(skip_checks=['mikepolicies_aws_1625063842021'])) self.assertEqual(len([r for r in report.failed_checks if r.check_id == 'mikepolicies_aws_1625063842021']), 0) self.assertEqual(len([r for r in report.failed_checks if r.check_id == 'mikepolicies_AWS_1625063607541']), 1) report = cfn_runner.run(root_folder=test_files_dir, runner_filter=RunnerFilter(checks=['kpande_AWS_1635187541652'])) self.assertEqual(len([r for r in report.failed_checks if r.check_id == 'kpande_AWS_1635187541652']), 6) self.assertEqual(len([r for r in report.failed_checks if r.check_id == 'kpande_AWS_1635180094606']), 0) report = cfn_runner.run(root_folder=test_files_dir, runner_filter=RunnerFilter(checks=['kpande_AWS_1635180094606'])) self.assertEqual(len([r for r in report.failed_checks if r.check_id == 'kpande_AWS_1635180094606']), 1) self.assertEqual(len([r for r in report.failed_checks if r.check_id == 'kpande_AWS_1635187541652']), 0) report = cfn_runner.run(root_folder=test_files_dir, runner_filter=RunnerFilter(skip_checks=['kpande_AWS_1635180094606'])) self.assertEqual(len([r for r in report.failed_checks if r.check_id == 'kpande_AWS_1635180094606']), 0) self.assertEqual(len([r for r in report.failed_checks if r.check_id == 'kpande_AWS_1635187541652']), 6)
def get_checks_registry(): registry = Registry(parser=NXGraphCheckParser(), checks_dir=str( Path( __file__).parent.parent.parent.parent.parent / "checkov" / "cloudformation" / "checks" / "graph_checks")) registry.load_checks() return registry
def __init__(self, bc_integration): super().__init__(bc_integration, order=0) self.policies = {} self.platform_policy_parser = NXGraphCheckParser() self.policies_url = f"{self.bc_integration.api_url}/api/v1/policies/table/data" self.bc_cloned_checks: Dict[str, List[dict]] = defaultdict(list)
def __init__(self, bc_integration): super().__init__(bc_integration, order=0) self.policies = {} self.platform_policy_parser = NXGraphCheckParser()
def test_valid_yaml_but_invalid_check_does_not_throw_exception(self): current_dir = os.path.dirname(os.path.realpath(__file__)) test_files_dir = current_dir + "/test-registry-data/valid-yaml-invalid-check" r = Registry(checks_dir=test_files_dir, parser=NXGraphCheckParser()) r.load_checks()
def test_policy_load(self): # response from API policies = [{ "provider": "AWS", "id": "mikepolicies_AWS_1625063607541", "title": "yaml1", "severity": "MEDIUM", "category": "General", "resourceTypes": ["aws_s3_bucket"], "accountsData": { "mikeurbanski1/terragoat3": { "amounts": { "CLOSED": 0, "DELETED": 0, "OPEN": 1, "REMEDIATED": 0, "SUPPRESSED": 0 }, "lastUpdateDate": "2021-06-30T14:33:54.638Z" } }, "guideline": "yaml1", "isCustom": True, "conditionQuery": { "or": [{ "value": "xyz", "operator": "equals", "attribute": "xyz", "cond_type": "attribute", "resource_types": ["aws_s3_bucket"] }] }, "benchmarks": {}, "createdBy": "*****@*****.**", "code": "---\nmetadata:\n name: \"yaml1\" #give your custom policy a unique name \n guidelines: \"yaml1\" #add text that explains the configuration the policy looks for, its implications, and how to fix it\n category: \"general\" #choose one: \"general\"/\"elaticsearch\"/\"iam\"/\"kubernetes\"/\"logging\"/\"monitoring\"/\"networking\"/\"public\"/\"secrets\"/\"serverless\"/\"storage\"\n severity: \"medium\" #choose one: \"critical\"/\"high\"/\"medium\"/\"low\"/\"info\"\nscope:\n provider: \"aws\" #choose one: \"aws\"/\"azure\"/\"gcp\"\ndefinition: #define the conditions the policy searches for.\n or:\n - cond_type: \"attribute\"\n resource_types:\n - \"aws_s3_bucket\"\n attribute: \"xyz\"\n operator: \"equals\"\n value: \"xyz\"\n# - cond_type: \"attribute\"\n# resource_types:\n# - \"aws_instance\"\n# attribute: \"instance_type\"\n# operator: \"equals\"\n# value: \"t3.nano\"\n" }, { "provider": "AWS", "id": "mikepolicies_aws_1625063842021", "title": "ui1", "severity": "HIGH", "category": "General", "resourceTypes": ["aws_s3_bucket"], "accountsData": { "mikeurbanski1/terragoat3": { "amounts": { "CLOSED": 0, "DELETED": 0, "OPEN": 1, "REMEDIATED": 0, "SUPPRESSED": 0 }, "lastUpdateDate": "2021-06-30T14:42:29.534Z" } }, "guideline": "ui1", "isCustom": True, "conditionQuery": { "value": "abc", "operator": "equals", "attribute": "region", "cond_type": "attribute", "resource_types": ["aws_s3_bucket"] }, "benchmarks": {}, "createdBy": "*****@*****.**", "code": None }] # for this test, we simulate some of the check registry manipulation; otherwise the singleton # instance will be modified and break other tests. parser = NXGraphCheckParser() registry = Registry( parser=NXGraphCheckParser(), checks_dir=str( Path(__file__).parent.parent.parent.parent / "checkov" / "terraform" / "checks" / "graph_checks")) checks = [ parser.parse_raw_check( CustomPoliciesIntegration._convert_raw_check(p)) for p in policies ] registry.checks = checks # simulate that the policy downloader will do runner = Runner(external_registries=[registry]) current_dir = os.path.dirname(os.path.realpath(__file__)) test_files_dir = current_dir + "/example_custom_policy_dir" report = runner.run(root_folder=test_files_dir, runner_filter=RunnerFilter()) self.assertEqual( len([ r for r in report.failed_checks if r.check_id == 'mikepolicies_aws_1625063842021' ]), 1) self.assertEqual( len([ r for r in report.failed_checks if r.check_id == 'mikepolicies_AWS_1625063607541' ]), 1) report = runner.run(root_folder=test_files_dir, runner_filter=RunnerFilter( checks=['mikepolicies_aws_1625063842021'])) self.assertEqual( len([ r for r in report.failed_checks if r.check_id == 'mikepolicies_aws_1625063842021' ]), 1) self.assertEqual( len([ r for r in report.failed_checks if r.check_id == 'mikepolicies_AWS_1625063607541' ]), 0) report = runner.run( root_folder=test_files_dir, runner_filter=RunnerFilter( skip_checks=['mikepolicies_aws_1625063842021'])) self.assertEqual( len([ r for r in report.failed_checks if r.check_id == 'mikepolicies_aws_1625063842021' ]), 0) self.assertEqual( len([ r for r in report.failed_checks if r.check_id == 'mikepolicies_AWS_1625063607541' ]), 1)