示例#1
0
    def check_definitions(self, root_folder, runner_filter, report):
        for file_abs_path, definition in self.definitions.items():

            cf_file = f"/{os.path.relpath(file_abs_path, root_folder)}"

            if isinstance(
                    definition,
                    dict) and TemplateSections.RESOURCES in definition.keys():
                for resource_name, resource in definition[
                        TemplateSections.RESOURCES].items():
                    resource_id = ContextParser.extract_cf_resource_id(
                        resource, resource_name)
                    # check that the resource can be parsed as a CF resource
                    if resource_id:
                        resource_context = self.context[file_abs_path][
                            TemplateSections.RESOURCES][resource_name]
                        entity_lines_range = [
                            resource_context['start_line'],
                            resource_context['end_line']
                        ]
                        entity_code_lines = resource_context['code_lines']
                        if entity_lines_range and entity_code_lines:
                            # TODO - Variable Eval Message!
                            variable_evaluations = {}
                            skipped_checks = ContextParser.collect_skip_comments(
                                entity_code_lines)
                            entity = {resource_name: resource}
                            results = cfn_registry.scan(
                                cf_file, entity, skipped_checks, runner_filter)
                            tags = cfn_utils.get_resource_tags(entity)
                            for check, check_result in results.items():
                                record = Record(
                                    check_id=check.id,
                                    bc_check_id=check.bc_id,
                                    check_name=check.name,
                                    check_result=check_result,
                                    code_block=entity_code_lines,
                                    file_path=cf_file,
                                    file_line_range=entity_lines_range,
                                    resource=resource_id,
                                    evaluations=variable_evaluations,
                                    check_class=check.__class__.__module__,
                                    file_abs_path=file_abs_path,
                                    entity_tags=tags)

                                breadcrumb = self.breadcrumbs.get(
                                    record.file_path, {}).get(record.resource)
                                if breadcrumb:
                                    record = GraphRecord(record, breadcrumb)
                                record.set_guideline(check.guideline)
                                report.add_record(record=record)
示例#2
0
    def get_graph_checks_report(self, root_folder,
                                runner_filter: RunnerFilter):
        report = Report(self.check_type)
        checks_results = {}
        for r in self.external_registries + [graph_registry]:
            r.load_checks()
            registry_results = r.run_checks(
                self.graph_manager.get_reader_traversal(), runner_filter)
            checks_results = {**checks_results, **registry_results}

        for check, check_results in checks_results.items():
            for check_result in check_results:
                entity = check_result['entity']
                entity_context, entity_evaluations = self.get_entity_context_and_evaluations(
                    entity)
                if entity_context:
                    full_file_path = entity[CustomAttributes.FILE_PATH]
                    copy_of_check_result = copy.deepcopy(check_result)
                    for skipped_check in entity_context.get(
                            'skipped_checks', []):
                        if skipped_check['id'] == check.id:
                            copy_of_check_result[
                                'result'] = CheckResult.SKIPPED
                            copy_of_check_result[
                                'suppress_comment'] = skipped_check[
                                    'suppress_comment']
                            break
                    copy_of_check_result['entity'] = entity.get(
                        CustomAttributes.CONFIG)
                    record = Record(
                        check_id=check.id,
                        check_name=check.name,
                        check_result=copy_of_check_result,
                        code_block=entity_context.get('code_lines'),
                        file_path=
                        f"/{os.path.relpath(full_file_path, root_folder)}",
                        file_line_range=[
                            entity_context.get('start_line'),
                            entity_context.get('end_line')
                        ],
                        resource=".".join(entity_context['definition_path']),
                        evaluations=entity_evaluations,
                        check_class=check.__class__.__module__,
                        file_abs_path=os.path.abspath(full_file_path))
                    breadcrumb = self.breadcrumbs.get(record.file_path,
                                                      {}).get(record.resource)
                    if breadcrumb:
                        record = GraphRecord(record, breadcrumb)

                    report.add_record(record=record)
        return report
示例#3
0
文件: runner.py 项目: tronxd/checkov
    def get_graph_checks_report(self, root_folder: str,
                                runner_filter: RunnerFilter) -> Report:
        report = Report(self.check_type)
        checks_results = self.run_graph_checks_results(runner_filter)

        for check, check_results in checks_results.items():
            for check_result in check_results:
                entity = check_result["entity"]
                entity_file_abs_path = entity.get(CustomAttributes.FILE_PATH)
                entity_file_path = scanned_file = f"/{os.path.relpath(entity_file_abs_path, root_folder)}"
                entity_name = entity.get(
                    CustomAttributes.BLOCK_NAME).split(".")[1]
                entity_context = self.context[entity_file_abs_path][
                    TemplateSections.RESOURCES][entity_name]

                record = Record(
                    check_id=check.id,
                    check_name=check.name,
                    check_result=check_result,
                    code_block=entity_context.get("code_lines"),
                    file_path=entity_file_path,
                    file_line_range=[
                        entity_context.get("start_line"),
                        entity_context.get("end_line")
                    ],
                    resource=entity.get(CustomAttributes.ID),
                    evaluations={},
                    check_class=check.__class__.__module__,
                    file_abs_path=entity_file_abs_path,
                    entity_tags={} if not entity.get("Tags") else
                    cfn_utils.parse_entity_tags(entity.get("Tags")))
                record.set_guideline(check.guideline)
                if self.breadcrumbs:
                    breadcrumb = self.breadcrumbs.get(record.file_path,
                                                      {}).get(record.resource)
                    if breadcrumb:
                        record = GraphRecord(record, breadcrumb)

                report.add_record(record=record)
        return report
示例#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)