diff --git a/CHANGELOG.md b/CHANGELOG.md index b8997aaa90..f72f723325 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,36 @@ # CHANGELOG -## [Unreleased](https://github.com/bridgecrewio/checkov/compare/3.2.488...HEAD) +## [Unreleased](https://github.com/bridgecrewio/checkov/compare/3.2.493...HEAD) + +## [3.2.493](https://github.com/bridgecrewio/checkov/compare/3.2.492...3.2.493) - 2025-11-12 + +### Feature + +- **general:** support skips for module for_each and count - [#7368](https://github.com/bridgecrewio/checkov/pull/7368) + +## [3.2.492](https://github.com/bridgecrewio/checkov/compare/3.2.491...3.2.492) - 2025-11-10 + +### Bug Fix + +- **terraform:** get_resource_tags handles more cases - [#7365](https://github.com/bridgecrewio/checkov/pull/7365) + +## [3.2.491](https://github.com/bridgecrewio/checkov/compare/3.2.490...3.2.491) - 2025-11-09 + +### Bug Fix + +- **terraform:** Graph report tags should be dict - [#7363](https://github.com/bridgecrewio/checkov/pull/7363) + +## [3.2.490](https://github.com/bridgecrewio/checkov/compare/3.2.489...3.2.490) - 2025-11-04 + +### Feature + +- **general:** Fix downloading of the external modules when ref is a shortened Git hash - [#7278](https://github.com/bridgecrewio/checkov/pull/7278) + +## [3.2.489](https://github.com/bridgecrewio/checkov/compare/3.2.488...3.2.489) - 2025-10-29 + +### Bug Fix + +- **helm:** Check HELM_NAMESPACE env var in CKV_K8S_21 - [#7355](https://github.com/bridgecrewio/checkov/pull/7355) ## [3.2.488](https://github.com/bridgecrewio/checkov/compare/3.2.487...3.2.488) - 2025-10-27 diff --git a/checkov/common/goget/github/get_git.py b/checkov/common/goget/github/get_git.py index 29015d2dbc..0dd2652306 100644 --- a/checkov/common/goget/github/get_git.py +++ b/checkov/common/goget/github/get_git.py @@ -15,7 +15,7 @@ except ImportError as e: git_import_error = e -COMMIT_ID_PATTERN = re.compile(r"\?(ref=)(?P([0-9a-f]{40}))") +COMMIT_ID_PATTERN = re.compile(r"\?(ref=)(?P([0-9a-f]{5,40}))") TAG_PATTERN = re.compile(r'\?(ref=)(?P(.*))') # technically should be with ?ref=tags/ but this catches both BRANCH_PATTERN = re.compile(r'\?(ref=heads/)(?P(.*))') diff --git a/checkov/common/output/report.py b/checkov/common/output/report.py index d8da7c3b85..51af285332 100644 --- a/checkov/common/output/report.py +++ b/checkov/common/output/report.py @@ -574,6 +574,10 @@ def handle_skipped_checks( if record.resource_address and record.resource_address.startswith("module."): module_path = record.resource_address[module_address_len:record.resource_address.index('.', module_address_len + 1)] + # For module with for_each or count, the module path will be module.module_name[(.*)]. We can + # ignore the index and the for_each value and just use the module name as it's not possible to + # skip checks for a specific instance of a module + module_path = module_path.split('[')[0] module_enrichments = enriched_resources.get(module_path, {}) for module_skip in module_enrichments.get("skipped_checks", []): if record.check_id in module_skip["id"]: diff --git a/checkov/terraform/base_runner.py b/checkov/terraform/base_runner.py index bdd1bec3a6..c42860b324 100644 --- a/checkov/terraform/base_runner.py +++ b/checkov/terraform/base_runner.py @@ -31,6 +31,7 @@ from checkov.terraform.graph_builder.local_graph import TerraformLocalGraph from checkov.terraform.graph_manager import TerraformGraphManager from checkov.terraform.image_referencer.manager import TerraformImageReferencerManager +from checkov.terraform.tag_providers import get_resource_tags from checkov.terraform.tf_parser import TFParser from checkov.common.util.env_vars_config import env_vars_config @@ -187,7 +188,7 @@ def get_graph_checks_report( entity_context.get("end_line", 1), ], resource=resource, - entity_tags=entity.get("tags", {}), + entity_tags=get_resource_tags(resource, entity_config), evaluations=None, check_class=check.__class__.__module__, file_abs_path=os.path.abspath(full_file_path), diff --git a/checkov/terraform/tag_providers/__init__.py b/checkov/terraform/tag_providers/__init__.py index ddbd5b33cb..173240dc4b 100644 --- a/checkov/terraform/tag_providers/__init__.py +++ b/checkov/terraform/tag_providers/__init__.py @@ -4,18 +4,28 @@ from checkov.terraform.tag_providers import azure from checkov.terraform.tag_providers import gcp -provider_tag_mapping = {"aws": aws.get_resource_tags, "azure": azure.get_resource_tags, "gcp": gcp.get_resource_tags} +provider_tag_mapping = {"aws": aws.get_resource_tags, "azure": azure.get_resource_tags, "gcp": gcp.get_resource_tags, + "google": gcp.get_resource_tags} def get_resource_tags(resource_type: str, entity_config: Dict[str, Any]) -> Optional[Dict[str, Any]]: if not isinstance(entity_config, dict): return None - if "_" not in resource_type: - return None # probably not a resource block - provider = resource_type[: resource_type.index("_")] - provider_tag_function = provider_tag_mapping.get(provider) + provider_tag = get_provider_tag(resource_type) + provider_tag_function = provider_tag_mapping.get(provider_tag) if provider_tag else None if provider_tag_function: return provider_tag_function(entity_config) else: return None + + +def get_provider_tag(resource_type: str) -> Optional[str]: + provider_tag = None + if 'aws' in resource_type: + provider_tag = "aws" + elif 'azure' in resource_type: + provider_tag = "azure" + elif 'gcp' in resource_type or 'google' in resource_type: + provider_tag = "gcp" + return provider_tag diff --git a/checkov/version.py b/checkov/version.py index b27b50d713..1ade9a5b6c 100644 --- a/checkov/version.py +++ b/checkov/version.py @@ -1 +1 @@ -version = '3.2.489' +version = '3.2.493' diff --git a/kubernetes/requirements.txt b/kubernetes/requirements.txt index 445201bf1e..d26f47dc23 100644 --- a/kubernetes/requirements.txt +++ b/kubernetes/requirements.txt @@ -1 +1 @@ -checkov==3.2.489 +checkov==3.2.493 diff --git a/tests/common/goget/test_goget_github.py b/tests/common/goget/test_goget_github.py index 3b63e41195..8930483b5c 100644 --- a/tests/common/goget/test_goget_github.py +++ b/tests/common/goget/test_goget_github.py @@ -108,6 +108,17 @@ def test_parse_commit_id(self): self.assertEqual("aa218f56b14c9653891f9e74264a383fa43fefbd", getter.commit_id, "Parsed source commit_id is wrong") + def test_parse_shortened_commit_id(self): + """Test parsing of shortened git commit IDs (5-39 characters).""" + url = "https://my-git.com/owner/repository-name?ref=aa218" + getter = GitGetter(url) + git_url = getter.extract_git_ref(url) + + self.assertEqual( + "https://my-git.com/owner/repository-name", git_url, "Parsed source url is wrong for 5-char commit" + ) + self.assertEqual("aa218", getter.commit_id, "Parsed source commit_id is wrong for 5-char commit") + @patch('checkov.common.goget.github.get_git.Repo') @patch('shutil.copytree') @patch('os.makedirs') diff --git a/tests/common/runner_registry/test_runner_registry_plan_enrichment.py b/tests/common/runner_registry/test_runner_registry_plan_enrichment.py index c591867858..84cdfecf7f 100644 --- a/tests/common/runner_registry/test_runner_registry_plan_enrichment.py +++ b/tests/common/runner_registry/test_runner_registry_plan_enrichment.py @@ -132,12 +132,11 @@ def test_enrichment_of_plan_report_with_for_each(self): report = runner_registry.run(repo_root_for_plan_enrichment=[repo_root], files=[str(valid_plan_path)])[0] - # TODO: after fixing module enrichment with skipped checks the failed checks will become skipped - self.assertEqual(len(report.failed_checks), 3) + self.assertEqual(len(report.failed_checks), 0) self.assertEqual(len(report.passed_checks), 0) - self.assertEqual(len(report.skipped_checks), 2) + self.assertEqual(len(report.skipped_checks), 5) def test_skip_check(self): diff --git a/tests/terraform/test_provider_tags.py b/tests/terraform/test_provider_tags.py new file mode 100644 index 0000000000..84f989cb71 --- /dev/null +++ b/tests/terraform/test_provider_tags.py @@ -0,0 +1,13 @@ +import pytest + +from checkov.terraform.tag_providers import get_provider_tag + + +@pytest.mark.parametrize("resource_type, expected", [ + ("aws_instance.example", "aws"), + ("module.test.aws_instance.example", "aws"), + ("azure_instance.example", "azure"), + ("google_instance.example", "gcp"), +]) +def test_get_provider_tag(resource_type, expected) -> None: + assert get_provider_tag(resource_type) == expected