def run(banner=checkov_banner): parser = argparse.ArgumentParser(description='Infrastructure as code static analysis') add_parser_args(parser) args = parser.parse_args() runner_filter = RunnerFilter(framework=args.framework, checks=args.check, skip_checks=args.skip_check) if outer_registry: runner_registry = outer_registry runner_registry.runner_filter = runner_filter else: runner_registry = RunnerRegistry(banner, runner_filter, tf_runner(), cfn_runner(), k8_runner(), sls_runner(), arm_runner(), tf_plan_runner()) if args.version: print(version) return if args.bc_api_key: if args.repo_id is None: parser.error("--repo-id argument is required when using --bc-api-key") if len(args.repo_id.split('/')) != 2: parser.error("--repo-id argument format should be 'organization/repository_name' E.g " "bridgecrewio/checkov") bc_integration.setup_bridgecrew_credentials(bc_api_key=args.bc_api_key, repo_id=args.repo_id) guidelines = {} if not args.no_guide: guidelines = bc_integration.get_guidelines() if args.check and args.skip_check: parser.error("--check and --skip-check can not be applied together. please use only one of them") return if args.list: print_checks(framework=args.framework) return external_checks_dir = get_external_checks_dir(args) if args.directory: for root_folder in args.directory: file = args.file scan_reports = runner_registry.run(root_folder=root_folder, external_checks_dir=external_checks_dir, files=file, guidelines=guidelines) if bc_integration.is_integration_configured(): bc_integration.persist_repository(root_folder) bc_integration.persist_scan_results(scan_reports) bc_integration.commit_repository(args.branch) runner_registry.print_reports(scan_reports, args) return elif args.file: scan_reports = runner_registry.run(external_checks_dir=external_checks_dir, files=args.file, guidelines=guidelines) if bc_integration.is_integration_configured(): files = [os.path.abspath(file) for file in args.file] root_folder = os.path.split(os.path.commonprefix(files))[0] bc_integration.persist_repository(root_folder) bc_integration.persist_scan_results(scan_reports) bc_integration.commit_repository(args.branch) runner_registry.print_reports(scan_reports, args) else: print(f"{banner}") bc_integration.onboarding()
def run(): parser = argparse.ArgumentParser(description='Add some integers.') parser.add_argument('-v', '--version', help='Checkov version', action='store_true') parser.add_argument('-d', '--directory', help='IaC root directory (can not be used together with --file). Can be repeated') parser.add_argument('-f', '--file', action='append', help='IaC file(can not be used together with --directory)') parser.add_argument('--external-checks-dir', action='append', help='Directory for custom checks to be loaded. Can be repeated') parser.add_argument('-l', '--list', help='List checks', action='store_true') parser.add_argument('-o', '--output', nargs='?', choices=['cli', 'json', 'junitxml'], default='cli', help='Report output format') args = parser.parse_args() if args.version: print(version) return if args.list: print_checks() return else: runner_registry = RunnerRegistry(tf_runner(), cfn_runner()) root_folder = args.directory file = args.file scan_reports = runner_registry.run(root_folder, external_checks_dir=args.external_checks_dir, files=file) runner_registry.print_reports(scan_reports, args)
def run_kubernetes_scan(): current_dir = os.path.dirname(os.path.realpath(__file__)) test_files_dir = os.path.join(current_dir, repo_name) runner_filter = RunnerFilter() runner_registry = RunnerRegistry(banner, runner_filter, k8_runner()) reports = runner_registry.run(root_folder=test_files_dir) assert len(reports) > 0
def test_multi_iac(self): current_dir = os.path.dirname(os.path.realpath(__file__)) test_files_dir = current_dir + "/example_multi_iac" runner_filter = RunnerFilter(framework=None, checks=None, skip_checks=None) runner_registry = RunnerRegistry( banner, runner_filter, tf_runner(), cfn_runner(), k8_runner() ) reports = runner_registry.run(root_folder=test_files_dir) for report in reports: self.assertGreater(len(report.passed_checks), 1)
def verify_empty_report(self, test_files_dir, files=None): runner_filter = RunnerFilter(framework=None, checks=None, skip_checks=None) runner_registry = RunnerRegistry( banner, runner_filter, tf_runner(), cfn_runner(), k8_runner() ) reports = runner_registry.run(root_folder=test_files_dir, files=files) for report in reports: self.assertEqual(report.failed_checks, []) self.assertEqual(report.skipped_checks, []) self.assertEqual(report.passed_checks, []) return runner_registry
def test_enrichment_of_plan_report_with_modules(self): allowed_checks = ["CKV_AWS_66", "CKV_AWS_158"] runner_registry = RunnerRegistry( banner, RunnerFilter(checks=allowed_checks, framework="terraform_plan"), tf_plan_runner()) repo_root = Path( __file__).parent / "plan_with_tf_modules_for_enrichment" valid_plan_path = repo_root / "tfplan.json" report = runner_registry.run(repo_root_for_plan_enrichment=repo_root, files=[valid_plan_path])[0] failed_check_ids = [c.check_id for c in report.failed_checks] passed_check_ids = [c.check_id for c in report.passed_checks] skipped_check_ids = [c.check_id for c in report.skipped_checks] expected_failed_check_ids = ["CKV_AWS_158", "CKV_AWS_158"] expected_passed_check_ids = ["CKV_AWS_66", "CKV_AWS_66"] expected_skipped_check_ids = [] enriched_data = set([(c.file_path, tuple(c.file_line_range), tuple(c.code_block)) for c in report.failed_checks]) expected_enriched_data = { ( f"/{Path.relative_to(valid_plan_path, Path.cwd())}", (16, 16), (), ), ( "log_group/main.tf", (1, 2), ( (1, 'resource "aws_cloudwatch_log_group" "not_encrypted" {\n' ), (2, "}\n"), ), ), } self.assertEqual(len(failed_check_ids), 2) self.assertEqual(failed_check_ids, expected_failed_check_ids) self.assertEqual(len(passed_check_ids), 2) self.assertEqual(passed_check_ids, expected_passed_check_ids) self.assertEqual(len(skipped_check_ids), 0) self.assertEqual(skipped_check_ids, expected_skipped_check_ids) self.assertEqual(enriched_data, expected_enriched_data)
def test_resource_counts(self): current_dir = os.path.dirname(os.path.realpath(__file__)) test_files_dir = current_dir + "/example_multi_iac" runner_filter = RunnerFilter(framework=None, checks=None, skip_checks=None) runner_registry = RunnerRegistry( banner, runner_filter, tf_runner(), cfn_runner(), k8_runner() ) reports = runner_registry.run(root_folder=test_files_dir) # The number of resources that will get scan results. Note that this may change if we add policies covering new resource types. counts_by_type = {"kubernetes": 10, "terraform": 3, "cloudformation": 4} for report in reports: self.assertEqual( counts_by_type[report.check_type], report.get_summary()["resource_count"], )
def test_valid_cyclonedx_bom(self): runners = ( tf_graph_runner(), tf_plan_runner(), ) registry = RunnerRegistry("", RunnerFilter(), *runners) scan_reports = registry.run( files=[join(dirname(__file__), 'fixtures/main.tf')]) self.assertEqual(len(scan_reports), 2) r = scan_reports[0] cyclonedx_bom = r.get_cyclonedx_bom() # outputter = get_instance(bom=cyclonedx_bom) # outputter.output_to_file(filename='/tmp/test.xml', allow_overwrite=True) self.assertEqual(len(cyclonedx_bom.get_components()), 1) first_component = cyclonedx_bom.get_components()[0] self.assertEqual(len(first_component.get_vulnerabilities()), 5)
def test_skip_check(self): allowed_checks = ["CKV_AWS_20", "CKV_AWS_28"] runner_registry = RunnerRegistry( banner, RunnerFilter(checks=allowed_checks, framework="terraform_plan"), tf_plan_runner()) repo_root = Path(__file__).parent / "plan_with_hcl_for_enrichment" valid_plan_path = repo_root / "tfplan.json" report = runner_registry.run(repo_root_for_plan_enrichment=[repo_root], files=[valid_plan_path])[0] failed_check_ids = {c.check_id for c in report.failed_checks} skipped_check_ids = {c.check_id for c in report.skipped_checks} expected_skipped_check_ids = {"CKV_AWS_20", "CKV_AWS_28"} self.assertEqual(len(failed_check_ids), 0) self.assertEqual(len(skipped_check_ids), 2) self.assertEqual(skipped_check_ids, expected_skipped_check_ids)
def run(banner=checkov_banner): parser = argparse.ArgumentParser( description='Infrastructure as code static analysis') parser.add_argument('-v', '--version', help='version', action='store_true') parser.add_argument( '-d', '--directory', action='append', help= 'IaC root directory (can not be used together with --file). Can be repeated' ) parser.add_argument( '-f', '--file', action='append', help='IaC file(can not be used together with --directory)') parser.add_argument( '--external-checks-dir', action='append', help='Directory for custom checks to be loaded. Can be repeated') parser.add_argument('-l', '--list', help='List checks', action='store_true') parser.add_argument( '-o', '--output', nargs='?', choices=['cli', 'json', 'junitxml', 'github_failed_only'], default='cli', help='Report output format') parser.add_argument( '--framework', help= 'filter scan to run only on a specific infrastructure code frameworks', choices=['cloudformation', 'terraform', 'kubernetes', 'all'], default='all') parser.add_argument( '-c', '--check', help= 'filter scan to run only on a specific check identifier(whitelist), You can ' 'specify multiple checks separated by comma delimiter', default=None) parser.add_argument( '--skip-check', help= 'filter scan to run on all check but a specific check identifier(blacklist), You can ' 'specify multiple checks separated by comma delimiter', default=None) parser.add_argument('-s', '--soft-fail', help='Runs checks but suppresses error code', action='store_true') parser.add_argument('--bc-api-key', help='Bridgecrew API key') parser.add_argument( '--repo-id', help= 'Identity string of the repository, with form <repo_owner>/<repo_name>' ) parser.add_argument( '-b', '--branch', help= "Selected branch of the persisted repository. Only has effect when using the --bc-api-key flag", default='master') args = parser.parse_args() bc_integration = BcPlatformIntegration() runner_filter = RunnerFilter(framework=args.framework, checks=args.check, skip_checks=args.skip_check) runner_registry = RunnerRegistry(banner, runner_filter, tf_runner(), cfn_runner(), k8_runner()) if args.version: print(version) return if args.bc_api_key: if args.repo_id is None: parser.error( "--repo-id argument is required when using --bc-api-key") if len(args.repo_id.split('/')) != 2: parser.error( "--repo-id argument format should be 'organization/repository_name' E.g " "bridgecrewio/checkov") bc_integration.setup_bridgecrew_credentials(bc_api_key=args.bc_api_key, repo_id=args.repo_id) if args.check and args.skip_check: parser.error( "--check and --skip-check can not be applied together. please use only one of them" ) return if args.list: print_checks() return if args.directory: for root_folder in args.directory: file = args.file scan_reports = runner_registry.run( root_folder=root_folder, external_checks_dir=args.external_checks_dir, files=file) if bc_integration.is_integration_configured(): bc_integration.persist_repository(root_folder) bc_integration.persist_scan_results(scan_reports) bc_integration.commit_repository(args.branch) runner_registry.print_reports(scan_reports, args) return elif args.file: scan_reports = runner_registry.run( external_checks_dir=args.external_checks_dir, files=args.file) if bc_integration.is_integration_configured(): files = [os.path.abspath(file) for file in args.file] root_folder = os.path.split(os.path.commonprefix(files))[0] bc_integration.persist_repository(root_folder) bc_integration.persist_scan_results(scan_reports) bc_integration.commit_repository(args.branch) runner_registry.print_reports(scan_reports, args) else: print("No argument given. Try ` --help` for further information")
def run(banner=checkov_banner, argv=sys.argv[1:]): parser = argparse.ArgumentParser( description='Infrastructure as code static analysis') add_parser_args(parser) args = parser.parse_args(argv) # Disable runners with missing system dependencies args.skip_framework = runnerDependencyHandler.disable_incompatible_runners( args.skip_framework) runner_filter = RunnerFilter( framework=args.framework, skip_framework=args.skip_framework, checks=args.check, skip_checks=args.skip_check, download_external_modules=convert_str_to_bool( args.download_external_modules), external_modules_download_path=args.external_modules_download_path, evaluate_variables=convert_str_to_bool(args.evaluate_variables), runners=checkov_runners) if outer_registry: runner_registry = outer_registry runner_registry.runner_filter = runner_filter else: runner_registry = RunnerRegistry(banner, runner_filter, tf_runner(), cfn_runner(), k8_runner(), sls_runner(), arm_runner(), tf_plan_runner(), helm_runner()) if args.version: print(version) return if args.bc_api_key: if args.repo_id is None: parser.error( "--repo-id argument is required when using --bc-api-key") if len(args.repo_id.split('/')) != 2: parser.error( "--repo-id argument format should be 'organization/repository_name' E.g " "bridgecrewio/checkov") source = os.getenv('BC_SOURCE', 'cli') source_version = os.getenv('BC_SOURCE_VERSION', version) logger.debug(f'BC_SOURCE = {source}, version = {source_version}') try: bc_integration.setup_bridgecrew_credentials( bc_api_key=args.bc_api_key, repo_id=args.repo_id, skip_fixes=args.skip_fixes, skip_suppressions=args.skip_suppressions, source=source, source_version=source_version) except Exception as e: logger.error( 'An error occurred setting up the Bridgecrew platform integration. Please check your API token and try again.', exc_info=True) return guidelines = {} if not args.no_guide: guidelines = bc_integration.get_guidelines() if args.check and args.skip_check: parser.error( "--check and --skip-check can not be applied together. please use only one of them" ) return if args.list: print_checks(framework=args.framework) return external_checks_dir = get_external_checks_dir(args) url = None if args.directory: for root_folder in args.directory: file = args.file scan_reports = runner_registry.run( root_folder=root_folder, external_checks_dir=external_checks_dir, files=file, guidelines=guidelines, bc_integration=bc_integration) if bc_integration.is_integration_configured(): bc_integration.persist_repository(root_folder) bc_integration.persist_scan_results(scan_reports) url = bc_integration.commit_repository(args.branch) runner_registry.print_reports(scan_reports, args, url) return elif args.file: scan_reports = runner_registry.run( external_checks_dir=external_checks_dir, files=args.file, guidelines=guidelines, bc_integration=bc_integration) if bc_integration.is_integration_configured(): files = [os.path.abspath(file) for file in args.file] root_folder = os.path.split(os.path.commonprefix(files))[0] bc_integration.persist_repository(root_folder) bc_integration.persist_scan_results(scan_reports) url = bc_integration.commit_repository(args.branch) runner_registry.print_reports(scan_reports, args, url) else: print(f"{banner}") bc_integration.onboarding()
def test_enrichment_of_plan_report(self): allowed_checks = [ "CKV_AWS_19", "CKV_AWS_20", "CKV_AWS_28", "CKV_AWS_63", "CKV_AWS_119" ] runner_registry = RunnerRegistry( banner, RunnerFilter(checks=allowed_checks, framework="terraform_plan"), tf_plan_runner()) repo_root = Path(__file__).parent / "plan_with_hcl_for_enrichment" valid_plan_path = repo_root / "tfplan.json" report = runner_registry.run(repo_root_for_plan_enrichment=repo_root, files=[valid_plan_path])[0] failed_check_ids = {c.check_id for c in report.failed_checks} skipped_check_ids = {c.check_id for c in report.skipped_checks} expected_failed_check_ids = {"CKV_AWS_19", "CKV_AWS_63", "CKV_AWS_119"} expected_skipped_check_ids = {"CKV_AWS_20", "CKV_AWS_28"} enriched_data = {(c.file_path, tuple(c.file_line_range), tuple(c.code_block)) for c in report.failed_checks} expected_enriched_data = { ( "iam.tf", (1, 19), ( (1, 'resource "aws_iam_policy" "policy" {\n'), (2, ' name = "my_policy-123456789101"\n'), (3, ' path = "/"\n'), (4, ' description = "My test policy"\n'), (5, " policy = <<EOF\n"), (6, "{\n"), (7, ' "Version": "2012-10-17",\n'), (8, ' "Statement": [\n'), (9, " {\n"), (10, ' "Action": [\n'), (11, ' "*"\n'), (12, " ],\n"), (13, ' "Effect": "Allow",\n'), (14, ' "Resource": "arn:aws:iam::${var.aws_account_id}:role/admin"\n' ), (15, " }\n"), (16, " ]\n"), (17, "}\n"), (18, "EOF\n"), (19, "}"), ), ), ( "s3.tf", (1, 17), ( (1, 'resource "aws_s3_bucket" "test-bucket1" {\n'), (2, ' bucket = "test-bucket1"\n'), (3, " # checkov:skip=CKV_AWS_20: The bucket is a public static content " "host\n"), (4, ' acl = "public-read"\n'), (5, " lifecycle_rule {\n"), (6, ' id = "90 Day Lifecycle"\n'), (7, " enabled = true\n"), (8, " expiration {\n"), (9, " days = 90\n"), (10, " }\n"), (11, " noncurrent_version_expiration {\n"), (12, " days = 90\n"), (13, " }\n"), (14, " abort_incomplete_multipart_upload_days = 90\n"), (15, " }\n"), (16, " provider = aws.current_region\n"), (17, "}"), ), ), ( "dynamodb.tf", (1, 12), ( (1, 'resource "aws_dynamodb_table" "cross-environment-violations" {\n' ), (2, " # checkov:skip=CKV_AWS_28: ignoring backups for now\n" ), (3, ' name = "CrossEnvironmentViolations"\n'), (4, " read_capacity = 20\n"), (5, " write_capacity = 20\n"), (6, ' hash_key = "id"\n'), (7, " attribute {\n"), (8, ' name = "id"\n'), (9, ' type = "S"\n'), (10, " }\n"), (11, " provider = aws.current_region\n"), (12, "}"), ), ), } self.assertEqual(len(failed_check_ids), 3) self.assertEqual(failed_check_ids, expected_failed_check_ids) self.assertEqual(len(skipped_check_ids), 2) self.assertEqual(skipped_check_ids, expected_skipped_check_ids) self.assertEqual(enriched_data, expected_enriched_data)
def run(banner=checkov_banner, argv=sys.argv[1:]): default_config_paths = get_default_config_paths(sys.argv[1:]) parser = ExtArgumentParser( description='Infrastructure as code static analysis', default_config_files=default_config_paths, config_file_parser_class=configargparse.YAMLConfigFileParser, add_env_var_help=True) add_parser_args(parser) argcomplete.autocomplete(parser) config = parser.parse_args(argv) if config.add_check: resp = prompt.Prompt() check = prompt.Check(resp.responses) check.action() return # Check if --output value is None. If so, replace with ['cli'] for default cli output. if config.output is None: config.output = ['cli'] logger.debug(f'Checkov version: {version}') logger.debug(f'Python executable: {sys.executable}') logger.debug(f'Python version: {sys.version}') logger.debug(f'Checkov executable (argv[0]): {sys.argv[0]}') logger.debug(parser.format_values(sanitize=True)) # bridgecrew uses both the urllib3 and requests libraries, while checkov uses the requests library. # Allow the user to specify a CA bundle to be used by both libraries. bc_integration.setup_http_manager(config.ca_certificate) # if a repo is passed in it'll save it. Otherwise a default will be created based on the file or dir config.repo_id = bc_integration.persist_repo_id(config) # if a bc_api_key is passed it'll save it. Otherwise it will check ~/.bridgecrew/credentials config.bc_api_key = bc_integration.persist_bc_api_key(config) excluded_paths = config.skip_path or [] if config.var_file: config.var_file = [os.path.abspath(f) for f in config.var_file] runner_filter = RunnerFilter( framework=config.framework, skip_framework=config.skip_framework, checks=config.check, skip_checks=config.skip_check, download_external_modules=convert_str_to_bool( config.download_external_modules), external_modules_download_path=config.external_modules_download_path, evaluate_variables=convert_str_to_bool(config.evaluate_variables), runners=checkov_runners, excluded_paths=excluded_paths, all_external=config.run_all_external_checks, var_files=config.var_file) if outer_registry: runner_registry = outer_registry runner_registry.runner_filter = runner_filter else: runner_registry = RunnerRegistry(banner, runner_filter, *DEFAULT_RUNNERS) runnerDependencyHandler = RunnerDependencyHandler(runner_registry) runnerDependencyHandler.validate_runner_deps() if config.show_config: print(parser.format_values()) return if config.bc_api_key == '': parser.error( 'The --bc-api-key flag was specified but the value was blank. If this value was passed as a ' 'secret, you may need to double check the mapping.') elif config.bc_api_key: logger.debug(f'Using API key ending with {config.bc_api_key[-8:]}') if config.repo_id is None and not config.list: # if you are only listing policies, then the API key will be used to fetch policies, but that's it, # so the repo is not required parser.error( "--repo-id argument is required when using --bc-api-key") elif config.repo_id: repo_id_sections = config.repo_id.split('/') if len(repo_id_sections) < 2 or any( len(section) == 0 for section in repo_id_sections): parser.error( "--repo-id argument format should be 'organization/repository_name' E.g " "bridgecrewio/checkov") source_env_val = os.getenv('BC_SOURCE', 'cli') source = get_source_type(source_env_val) if source == SourceTypes[BCSourceType.DISABLED]: logger.warning( f'Received unexpected value for BC_SOURCE: {source_env_val}; Should be one of {{{",".join(SourceTypes.keys())}}} setting source to DISABLED' ) source_version = os.getenv('BC_SOURCE_VERSION', version) logger.debug(f'BC_SOURCE = {source.name}, version = {source_version}') if config.list: # This speeds up execution by not setting up upload credentials (since we won't upload anything anyways) logger.debug('Using --list; setting source to DISABLED') source = SourceTypes[BCSourceType.DISABLED] try: bc_integration.bc_api_key = config.bc_api_key bc_integration.setup_bridgecrew_credentials( repo_id=config.repo_id, skip_fixes=config.skip_fixes, skip_suppressions=config.skip_suppressions, skip_policy_download=config.skip_policy_download, source=source, source_version=source_version, repo_branch=config.branch) platform_excluded_paths = bc_integration.get_excluded_paths() or [] runner_filter.excluded_paths = runner_filter.excluded_paths + platform_excluded_paths except Exception: if bc_integration.prisma_url: message = 'An error occurred setting up the Bridgecrew platform integration. Please check your API ' \ 'token and PRISMA_API_URL environment variable and try again. The PRISMA_API_URL value ' \ 'should be similar to: `https://api0.prismacloud.io`' else: message = 'An error occurred setting up the Bridgecrew platform integration. Please check your API ' \ 'token and try again.' if logger.isEnabledFor(logging.DEBUG): logger.debug(message, exc_info=True) else: logger.error(message) return else: logger.debug('No API key found. Scanning locally only.') if config.check and config.skip_check: if any(item in runner_filter.checks for item in runner_filter.skip_checks): parser.error( "The check ids specified for '--check' and '--skip-check' must be mutually exclusive." ) return integration_feature_registry.run_pre_scan() guidelines = {} BC_SKIP_MAPPING = os.getenv("BC_SKIP_MAPPING", "FALSE") if config.no_guide or BC_SKIP_MAPPING.upper() == "TRUE": bc_integration.bc_skip_mapping = True else: guidelines = bc_integration.get_guidelines() ckv_to_bc_mapping = bc_integration.get_ckv_to_bc_id_mapping() if ckv_to_bc_mapping: all_checks = BaseCheckRegistry.get_all_registered_checks() for check in all_checks: check.bc_id = ckv_to_bc_mapping.get(check.id) if config.list: print_checks(frameworks=config.framework, use_bc_ids=config.output_bc_ids) return baseline = None if config.baseline: baseline = Baseline() baseline.from_json(config.baseline) external_checks_dir = get_external_checks_dir(config) url = None created_baseline_path = None if config.directory: exit_codes = [] for root_folder in config.directory: file = config.file scan_reports = runner_registry.run( root_folder=root_folder, external_checks_dir=external_checks_dir, files=file, guidelines=guidelines) if baseline: baseline.compare_and_reduce_reports(scan_reports) if bc_integration.is_integration_configured(): bc_integration.persist_repository( root_folder, excluded_paths=runner_filter.excluded_paths) bc_integration.persist_scan_results(scan_reports) url = bc_integration.commit_repository(config.branch) if config.create_baseline: overall_baseline = Baseline() for report in scan_reports: overall_baseline.add_findings_from_report(report) created_baseline_path = os.path.join( os.path.abspath(root_folder), '.checkov.baseline') with open(created_baseline_path, 'w') as f: json.dump(overall_baseline.to_dict(), f, indent=4) exit_codes.append( runner_registry.print_reports( scan_reports, config, url=url, created_baseline_path=created_baseline_path, baseline=baseline)) exit_code = 1 if 1 in exit_codes else 0 return exit_code elif config.file: scan_reports = runner_registry.run( external_checks_dir=external_checks_dir, files=config.file, guidelines=guidelines, repo_root_for_plan_enrichment=config.repo_root_for_plan_enrichment) if baseline: baseline.compare_and_reduce_reports(scan_reports) if config.create_baseline: overall_baseline = Baseline() for report in scan_reports: overall_baseline.add_findings_from_report(report) created_baseline_path = os.path.join( os.path.abspath(os.path.commonprefix(config.file)), '.checkov.baseline') with open(created_baseline_path, 'w') as f: json.dump(overall_baseline.to_dict(), f, indent=4) if bc_integration.is_integration_configured(): files = [os.path.abspath(file) for file in config.file] root_folder = os.path.split(os.path.commonprefix(files))[0] bc_integration.persist_repository( root_folder, files, excluded_paths=runner_filter.excluded_paths) bc_integration.persist_scan_results(scan_reports) url = bc_integration.commit_repository(config.branch) return runner_registry.print_reports( scan_reports, config, url=url, created_baseline_path=created_baseline_path, baseline=baseline) elif config.docker_image: if config.bc_api_key is None: parser.error( "--bc-api-key argument is required when using --docker-image") return if config.dockerfile_path is None: parser.error( "--dockerfile-path argument is required when using --docker-image" ) return if config.branch is None: parser.error( "--branch argument is required when using --docker-image") return bc_integration.commit_repository(config.branch) image_scanner.scan(config.docker_image, config.dockerfile_path) elif not config.quiet: print(f"{banner}") bc_integration.onboarding()
def run(banner=checkov_banner): parser = argparse.ArgumentParser( description='Infrastructure as code static analysis') parser.add_argument('-v', '--version', help='version', action='store_true') parser.add_argument( '-d', '--directory', action='append', help= 'IaC root directory (can not be used together with --file). Can be repeated' ) parser.add_argument( '-f', '--file', action='append', help='IaC file(can not be used together with --directory)') parser.add_argument( '--external-checks-dir', action='append', help='Directory for custom checks to be loaded. Can be repeated') parser.add_argument('-l', '--list', help='List checks', action='store_true') parser.add_argument('-o', '--output', nargs='?', choices=['cli', 'json', 'junitxml'], default='cli', help='Report output format') parser.add_argument('-s', '--soft-fail', help='Runs checks but suppresses error code', action='store_true') parser.add_argument('--bc-api-key', help='Bridgecrew API key') parser.add_argument( '--repo-id', help= 'Identity string of the repository, with form <repo_owner>/<repo_name>' ) parser.add_argument( '-b', '--branch', help= "Selected branch of the persisted repository. Only has effect when using the --bc-api-key flag", default='master') args = parser.parse_args() bc_integration = BcPlatformIntegration() runner_registry = RunnerRegistry(banner, tf_runner(), cfn_runner()) if args.version: print(version) return if args.bc_api_key: if args.repo_id is None: parser.error( "--repo-id argument is required when using --bc-api-key") bc_integration.setup_bridgecrew_credentials(bc_api_key=args.bc_api_key, repo_id=args.repo_id) if args.list: print_checks() return if args.directory: for root_folder in args.directory: file = args.file scan_reports = runner_registry.run( root_folder=root_folder, external_checks_dir=args.external_checks_dir, files=file) if bc_integration.is_integration_configured(): bc_integration.persist_repository(root_folder) bc_integration.persist_scan_results(scan_reports) bc_integration.commit_repository(args.branch) runner_registry.print_reports(scan_reports, args) return elif args.file: scan_reports = runner_registry.run( external_checks_dir=args.external_checks_dir, files=args.file) if bc_integration.is_integration_configured(): files = [os.path.abspath(file) for file in args.file] root_folder = os.path.split(os.path.commonprefix(files))[0] bc_integration.persist_repository(root_folder) bc_integration.persist_scan_results(scan_reports) bc_integration.commit_repository(args.branch) runner_registry.print_reports(scan_reports, args) else: print("No argument given. Try ` --help` for further information")
def run(banner=checkov_banner, argv=sys.argv[1:]): parser = argparse.ArgumentParser(description='Infrastructure as code static analysis') add_parser_args(parser) args = parser.parse_args(argv) # bridgecrew uses both the urllib3 and requests libraries, while checkov uses the requests library. # Allow the user to specify a CA bundle to be used by both libraries. bc_integration.setup_http_manager(args.ca_certificate) # Disable runners with missing system dependencies args.skip_framework = runnerDependencyHandler.disable_incompatible_runners(args.skip_framework) runner_filter = RunnerFilter(framework=args.framework, skip_framework=args.skip_framework, checks=args.check, skip_checks=args.skip_check, download_external_modules=convert_str_to_bool(args.download_external_modules), external_modules_download_path=args.external_modules_download_path, evaluate_variables=convert_str_to_bool(args.evaluate_variables), runners=checkov_runners) if outer_registry: runner_registry = outer_registry runner_registry.runner_filter = runner_filter else: runner_registry = RunnerRegistry(banner, runner_filter, tf_graph_runner(), cfn_runner(), k8_runner(), sls_runner(), arm_runner(), tf_plan_runner(), helm_runner(),dockerfile_runner()) if args.version: print(version) return if args.bc_api_key == '': parser.error('The --bc-api-key flag was specified but the value was blank. If this value was passed as a secret, you may need to double check the mapping.') elif args.bc_api_key: logger.debug(f'Using API key ending with {args.bc_api_key[-8:]}') if args.repo_id is None: parser.error("--repo-id argument is required when using --bc-api-key") if len(args.repo_id.split('/')) != 2: parser.error("--repo-id argument format should be 'organization/repository_name' E.g " "bridgecrewio/checkov") source = os.getenv('BC_SOURCE', 'cli') source_version = os.getenv('BC_SOURCE_VERSION', version) logger.debug(f'BC_SOURCE = {source}, version = {source_version}') try: bc_integration.setup_bridgecrew_credentials(bc_api_key=args.bc_api_key, repo_id=args.repo_id, skip_fixes=args.skip_fixes, skip_suppressions=args.skip_suppressions, source=source, source_version=source_version, repo_branch=args.branch) except Exception as e: logger.error('An error occurred setting up the Bridgecrew platform integration. Please check your API token and try again.', exc_info=True) return else: logger.debug('No API key found. Scanning locally only.') guidelines = {} if not args.no_guide: guidelines = bc_integration.get_guidelines() if args.check and args.skip_check: parser.error("--check and --skip-check can not be applied together. please use only one of them") return if args.list: print_checks(framework=args.framework) return external_checks_dir = get_external_checks_dir(args) url = None if args.directory: exit_codes = [] for root_folder in args.directory: file = args.file scan_reports = runner_registry.run(root_folder=root_folder, external_checks_dir=external_checks_dir, files=file, guidelines=guidelines, bc_integration=bc_integration) if bc_integration.is_integration_configured(): bc_integration.persist_repository(root_folder) bc_integration.persist_scan_results(scan_reports) url = bc_integration.commit_repository(args.branch) exit_codes.append(runner_registry.print_reports(scan_reports, args, url)) exit_code = 1 if 1 in exit_codes else 0 return exit_code elif args.file: scan_reports = runner_registry.run(external_checks_dir=external_checks_dir, files=args.file, guidelines=guidelines, bc_integration=bc_integration) if bc_integration.is_integration_configured(): files = [os.path.abspath(file) for file in args.file] root_folder = os.path.split(os.path.commonprefix(files))[0] bc_integration.persist_repository(root_folder) bc_integration.persist_scan_results(scan_reports) url = bc_integration.commit_repository(args.branch) return runner_registry.print_reports(scan_reports, args, url) elif args.docker_image: if args.bc_api_key is None: parser.error("--bc-api-key argument is required when using --docker-image") return if args.dockerfile_path is None: parser.error("--dockerfile-path argument is required when using --docker-image") return if args.branch is None: parser.error("--branch argument is required when using --docker-image") return image_scanner.scan(args.docker_image, args.dockerfile_path) else: print(f"{banner}") bc_integration.onboarding()
def run(banner=checkov_banner, argv=sys.argv[1:]): default_config_paths = get_default_config_paths(sys.argv[1:]) parser = ExtArgumentParser( description='Infrastructure as code static analysis', default_config_files=default_config_paths, config_file_parser_class=configargparse.YAMLConfigFileParser, add_env_var_help=True) add_parser_args(parser) config = parser.parse_args(argv) # bridgecrew uses both the urllib3 and requests libraries, while checkov uses the requests library. # Allow the user to specify a CA bundle to be used by both libraries. bc_integration.setup_http_manager(config.ca_certificate) # if a repo is passed in it'll save it. Otherwise a default will be created based on the file or dir config.repo_id = bc_integration.persist_repo_id(config) # if a bc_api_key is passed it'll save it. Otherwise it will check ~/.bridgecrew/credentials config.bc_api_key = bc_integration.persist_bc_api_key(config) excluded_paths = config.skip_path or [] runner_filter = RunnerFilter( framework=config.framework, skip_framework=config.skip_framework, checks=config.check, skip_checks=config.skip_check, download_external_modules=convert_str_to_bool( config.download_external_modules), external_modules_download_path=config.external_modules_download_path, evaluate_variables=convert_str_to_bool(config.evaluate_variables), runners=checkov_runners, excluded_paths=excluded_paths, all_external=config.run_all_external_checks) if outer_registry: runner_registry = outer_registry runner_registry.runner_filter = runner_filter else: runner_registry = RunnerRegistry(banner, runner_filter, *DEFAULT_RUNNERS) runnerDependencyHandler = RunnerDependencyHandler(runner_registry) runnerDependencyHandler.validate_runner_deps() if config.show_config: print(parser.format_values()) return if config.bc_api_key == '': parser.error( 'The --bc-api-key flag was specified but the value was blank. If this value was passed as a secret, ' 'you may need to double check the mapping.') elif config.bc_api_key: logger.debug(f'Using API key ending with {config.bc_api_key[-8:]}') if config.repo_id is None: parser.error( "--repo-id argument is required when using --bc-api-key") if len(config.repo_id.split('/')) != 2: parser.error( "--repo-id argument format should be 'organization/repository_name' E.g " "bridgecrewio/checkov") source = os.getenv('BC_SOURCE', 'cli') source_version = os.getenv('BC_SOURCE_VERSION', version) logger.debug(f'BC_SOURCE = {source}, version = {source_version}') try: bc_integration.setup_bridgecrew_credentials( bc_api_key=config.bc_api_key, repo_id=config.repo_id, skip_fixes=config.skip_fixes, skip_suppressions=config.skip_suppressions, skip_policy_download=config.skip_policy_download, source=source, source_version=source_version, repo_branch=config.branch) platform_excluded_paths = bc_integration.get_excluded_paths() or [] runner_filter.excluded_paths = runner_filter.excluded_paths + platform_excluded_paths except Exception as e: logger.error( 'An error occurred setting up the Bridgecrew platform integration. Please check your API token' ' and try again.', exc_info=True) return else: logger.debug('No API key found. Scanning locally only.') guidelines = {} if not config.no_guide: guidelines = bc_integration.get_guidelines() if config.check and config.skip_check: if any(item in runner_filter.checks for item in runner_filter.skip_checks): parser.error( "The check ids specified for '--check' and '--skip-check' must be mutually exclusive." ) return integration_feature_registry.run_pre_scan() if config.list: print_checks(framework=config.framework) return baseline = None if config.baseline: baseline = Baseline() baseline.from_json(config.baseline) external_checks_dir = get_external_checks_dir(config) url = None created_baseline_path = None if config.directory: exit_codes = [] for root_folder in config.directory: file = config.file scan_reports = runner_registry.run( root_folder=root_folder, external_checks_dir=external_checks_dir, files=file, guidelines=guidelines) if baseline: baseline.compare_and_reduce_reports(scan_reports) if bc_integration.is_integration_configured(): bc_integration.persist_repository( root_folder, excluded_paths=runner_filter.excluded_paths) bc_integration.persist_scan_results(scan_reports) url = bc_integration.commit_repository(config.branch) if config.create_baseline: overall_baseline = Baseline() for report in scan_reports: overall_baseline.add_findings_from_report(report) created_baseline_path = os.path.join( os.path.abspath(root_folder), '.checkov.baseline') with open(created_baseline_path, 'w') as f: json.dump(overall_baseline.to_dict(), f, indent=4) exit_codes.append( runner_registry.print_reports( scan_reports, config, url=url, created_baseline_path=created_baseline_path, baseline=baseline)) exit_code = 1 if 1 in exit_codes else 0 return exit_code elif config.file: scan_reports = runner_registry.run( external_checks_dir=external_checks_dir, files=config.file, guidelines=guidelines, repo_root_for_plan_enrichment=config.repo_root_for_plan_enrichment) if baseline: baseline.compare_and_reduce_reports(scan_reports) if config.create_baseline: overall_baseline = Baseline() for report in scan_reports: overall_baseline.add_findings_from_report(report) created_baseline_path = os.path.join( os.path.abspath(os.path.commonprefix(config.file)), '.checkov.baseline') with open(created_baseline_path, 'w') as f: json.dump(overall_baseline.to_dict(), f, indent=4) if bc_integration.is_integration_configured(): files = [os.path.abspath(file) for file in config.file] root_folder = os.path.split(os.path.commonprefix(files))[0] bc_integration.persist_repository( root_folder, files, excluded_paths=runner_filter.excluded_paths) bc_integration.persist_scan_results(scan_reports) url = bc_integration.commit_repository(config.branch) return runner_registry.print_reports( scan_reports, config, url=url, created_baseline_path=created_baseline_path, baseline=baseline) elif config.docker_image: if config.bc_api_key is None: parser.error( "--bc-api-key argument is required when using --docker-image") return if config.dockerfile_path is None: parser.error( "--dockerfile-path argument is required when using --docker-image" ) return if config.branch is None: parser.error( "--branch argument is required when using --docker-image") return bc_integration.commit_repository(config.branch) image_scanner.scan(config.docker_image, config.dockerfile_path) else: print(f"{banner}") bc_integration.onboarding()
def run(): parser = argparse.ArgumentParser( description='Infrastructure as code static analysis') parser.add_argument('-v', '--version', help='Checkov version', action='store_true') parser.add_argument( '-d', '--directory', action='append', help= 'IaC root directory (can not be used together with --file). Can be repeated' ) parser.add_argument( '-f', '--file', action='append', help='IaC file(can not be used together with --directory)') parser.add_argument( '--external-checks-dir', action='append', help='Directory for custom checks to be loaded. Can be repeated') parser.add_argument('-l', '--list', help='List checks', action='store_true') parser.add_argument('-o', '--output', nargs='?', choices=['cli', 'json', 'junitxml'], default='cli', help='Report output format') parser.add_argument('-s', '--soft-fail', help='Runs checks but suppresses error code', action='store_true') args = parser.parse_args() runner_registry = RunnerRegistry(tf_runner(), cfn_runner()) if args.version: print(version) return elif args.list: print_checks() return elif args.directory: for root_folder in args.directory: file = args.file scan_reports = runner_registry.run( root_folder, external_checks_dir=args.external_checks_dir, files=file) runner_registry.print_reports(scan_reports, args) return elif args.file: scan_reports = runner_registry.run( None, external_checks_dir=args.external_checks_dir, files=args.file) runner_registry.print_reports(scan_reports, args) else: print( "No argument given. Try `checkov --help` for further information")