예제 #1
0
파일: runner.py 프로젝트: xB-2048/checkov
    def run_block(self, entities,
                  definition_context,
                  full_file_path, root_folder, report, scanned_file,
                  block_type, runner_filter=None, entity_context_path_header=None):

        registry = self.block_type_registries[block_type]
        if not registry:
            return

        for entity in entities:
            entity_evaluations = None
            context_parser = parser_registry.context_parsers[block_type]
            definition_path = context_parser.get_entity_context_path(entity)
            entity_id = ".".join(definition_path)
            if entity_context_path_header is None:
                entity_context_path = [block_type] + definition_path
            else:
                entity_context_path = entity_context_path_header + block_type + definition_path
            # Entity can exist only once per dir, for file as well
            try:
                entity_context = dict_utils.getInnerDict(definition_context[full_file_path], entity_context_path)
                entity_lines_range = [entity_context.get('start_line'), entity_context.get('end_line')]
                entity_code_lines = entity_context.get('code_lines')
                skipped_checks = entity_context.get('skipped_checks')
            except KeyError:
                # TODO: Context info isn't working for modules
                entity_lines_range = None
                entity_code_lines = None
                skipped_checks = None

            if full_file_path in self.evaluations_context:
                variables_evaluations = {}
                for var_name, context_info in self.evaluations_context.get(full_file_path, {}).items():
                    variables_evaluations[var_name] = dataclasses.asdict(context_info)
                entity_evaluations = BaseVariableEvaluation.reduce_entity_evaluations(variables_evaluations,
                                                                                      entity_context_path)
            results = registry.scan(scanned_file, entity, skipped_checks, runner_filter)
            absolut_scanned_file_path = self._strip_module_referrer(file_path=full_file_path)
            # This duplicates a call at the start of scan, but adding this here seems better than kludging with some tuple return type
            (entity_type, _, entity_config) = registry.extract_entity_details(entity)
            tags = get_resource_tags(entity_type, entity_config)
            for check, check_result in results.items():
                record = Record(check_id=check.id, check_name=check.name, check_result=check_result,
                                code_block=entity_code_lines, file_path=scanned_file,
                                file_line_range=entity_lines_range,
                                resource=entity_id, evaluations=entity_evaluations,
                                check_class=check.__class__.__module__, file_abs_path=absolut_scanned_file_path, entity_tags=tags)
                report.add_record(record=record)
예제 #2
0
 def run_block(self,
               entities,
               definition_context,
               full_file_path,
               report,
               scanned_file,
               block_type,
               runner_filter=None):
     registry = self.block_type_registries[block_type]
     if registry:
         for entity in entities:
             entity_evaluations = None
             context_parser = parser_registry.context_parsers[block_type]
             definition_path = context_parser.get_entity_context_path(
                 entity)
             entity_id = ".".join(definition_path)
             entity_context_path = [block_type] + definition_path
             # Entity can exist only once per dir, for file as well
             entity_context = dict_utils.getInnerDict(
                 definition_context[full_file_path], entity_context_path)
             entity_lines_range = [
                 entity_context.get('start_line'),
                 entity_context.get('end_line')
             ]
             entity_code_lines = entity_context.get('code_lines')
             skipped_checks = entity_context.get('skipped_checks')
             variables_evaluations = definition_context[full_file_path].get(
                 'evaluations')
             if variables_evaluations:
                 entity_evaluations = BaseVariableEvaluation.reduce_entity_evaluations(
                     variables_evaluations, entity_context_path)
             results = registry.scan(scanned_file, entity, skipped_checks,
                                     runner_filter)
             for check, check_result in results.items():
                 record = Record(check_id=check.id,
                                 check_name=check.name,
                                 check_result=check_result,
                                 code_block=entity_code_lines,
                                 file_path=scanned_file,
                                 file_line_range=entity_lines_range,
                                 resource=entity_id,
                                 evaluations=entity_evaluations,
                                 check_class=check.__class__.__module__)
                 report.add_record(record=record)
예제 #3
0
    def get_enriched_resources(repo_root):
        tf_definitions = {}
        parsing_errors = {}
        Parser().parse_directory(
            directory=repo_root,  # assume plan file is in the repo-root
            out_definitions=tf_definitions,
            out_parsing_errors=parsing_errors,
        )

        enriched_resources = {}
        for full_file_path, definition in tf_definitions.items():
            definitions_context = parser_registry.enrich_definitions_context(
                (full_file_path, definition))
            abs_scanned_file, _ = tf_runner._strip_module_referrer(
                full_file_path)
            scanned_file = os.path.relpath(abs_scanned_file, repo_root)
            for block_type, block_value in definition.items():
                if block_type in CHECK_BLOCK_TYPES:
                    for entity in block_value:
                        context_parser = parser_registry.context_parsers[
                            block_type]
                        definition_path = context_parser.get_entity_context_path(
                            entity)
                        entity_id = ".".join(definition_path)
                        entity_context_path = [block_type] + definition_path
                        entity_context = dict_utils.getInnerDict(
                            definitions_context[full_file_path],
                            entity_context_path)
                        entity_lines_range = [
                            entity_context.get("start_line"),
                            entity_context.get("end_line"),
                        ]
                        entity_code_lines = entity_context.get("code_lines")
                        skipped_checks = entity_context.get("skipped_checks")
                        enriched_resources[entity_id] = {
                            "entity_code_lines": entity_code_lines,
                            "entity_lines_range": entity_lines_range,
                            "scanned_file": scanned_file,
                            "skipped_checks": skipped_checks
                        }
        return enriched_resources
예제 #4
0
    def run_block(self,
                  entities,
                  definition_context,
                  full_file_path,
                  root_folder,
                  report,
                  scanned_file,
                  block_type,
                  runner_filter=None,
                  entity_context_path_header=None,
                  module_referrer: Optional[str] = None):

        registry = self.block_type_registries[block_type]
        if not registry:
            return

        for entity in entities:
            entity_evaluations = None
            context_parser = parser_registry.context_parsers[block_type]
            definition_path = context_parser.get_entity_context_path(entity)
            entity_id = ".".join(
                definition_path)  # example: aws_s3_bucket.my_bucket

            caller_file_path = None
            caller_file_line_range = None

            if module_referrer is not None:
                referrer_id = self._find_id_for_referrer(
                    full_file_path, self.tf_definitions)
                if referrer_id:
                    entity_id = f"{referrer_id}.{entity_id}"  # ex: module.my_module.aws_s3_bucket.my_bucket
                    abs_caller_file = module_referrer[:module_referrer.
                                                      rindex("#")]
                    caller_file_path = f"/{os.path.relpath(abs_caller_file, root_folder)}"

                    try:
                        caller_context = dpath.get(
                            definition_context[abs_caller_file],
                            # HACK ALERT: module data is currently double-nested in
                            #             definition context. If fixed, remove the
                            #             addition of "module." at the beginning.
                            "module." + referrer_id,
                            separator=".")
                    except KeyError:
                        logging.debug("Unable to find caller context for: %s",
                                      abs_caller_file)
                        caller_context = None

                    if caller_context:
                        caller_file_line_range = [
                            caller_context.get('start_line'),
                            caller_context.get('end_line')
                        ]
                else:
                    logging.debug(
                        f"Unable to find referrer ID for full path: %s",
                        full_file_path)

            if entity_context_path_header is None:
                entity_context_path = [block_type] + definition_path
            else:
                entity_context_path = entity_context_path_header + block_type + definition_path
            # Entity can exist only once per dir, for file as well
            try:
                entity_context = dict_utils.getInnerDict(
                    definition_context[full_file_path], entity_context_path)
                entity_lines_range = [
                    entity_context.get('start_line'),
                    entity_context.get('end_line')
                ]
                entity_code_lines = entity_context.get('code_lines')
                skipped_checks = entity_context.get('skipped_checks')
            except KeyError:
                # TODO: Context info isn't working for modules
                entity_lines_range = None
                entity_code_lines = None
                skipped_checks = None

            if full_file_path in self.evaluations_context:
                variables_evaluations = {}
                for var_name, context_info in self.evaluations_context.get(
                        full_file_path, {}).items():
                    variables_evaluations[var_name] = dataclasses.asdict(
                        context_info)
                entity_evaluations = BaseVariableEvaluation.reduce_entity_evaluations(
                    variables_evaluations, entity_context_path)
            results = registry.scan(scanned_file, entity, skipped_checks,
                                    runner_filter)
            absolut_scanned_file_path, _ = self._strip_module_referrer(
                file_path=full_file_path)
            # This duplicates a call at the start of scan, but adding this here seems better than kludging with some tuple return type
            (entity_type, entity_name,
             entity_config) = registry.extract_entity_details(entity)
            tags = get_resource_tags(entity_type, entity_config)
            for check, check_result in results.items():
                record = Record(check_id=check.id,
                                check_name=check.name,
                                check_result=check_result,
                                code_block=entity_code_lines,
                                file_path=scanned_file,
                                file_line_range=entity_lines_range,
                                resource=entity_id,
                                evaluations=entity_evaluations,
                                check_class=check.__class__.__module__,
                                file_abs_path=absolut_scanned_file_path,
                                entity_tags=tags,
                                caller_file_path=caller_file_path,
                                caller_file_line_range=caller_file_line_range)
                breadcrumb = self.breadcrumbs.get(record.file_path, {}).get(
                    '.'.join([entity_type, entity_name]))
                if breadcrumb:
                    record = GraphRecord(record, breadcrumb)
                report.add_record(record=record)