diff --git a/checkov/terraform/checks/graph_checks/aws/EC2InstanceHasIAMRoleAttached.yaml b/checkov/terraform/checks/graph_checks/aws/EC2InstanceHasIAMRoleAttached.yaml new file mode 100644 index 00000000000..5af6d189614 --- /dev/null +++ b/checkov/terraform/checks/graph_checks/aws/EC2InstanceHasIAMRoleAttached.yaml @@ -0,0 +1,10 @@ +metadata: + id: "CKV2_AWS_41" + name: "Ensure an IAM role is attached to EC2 instance" + category: "IAM" +definition: + cond_type: "attribute" + resource_types: + - "aws_instance" + attribute: "iam_instance_profile" + operator: "exists" \ No newline at end of file diff --git a/checkov/terraform/checks/graph_checks/gcp/CloudFunctionSecureHTTPTrigger.yaml b/checkov/terraform/checks/graph_checks/gcp/CloudFunctionSecureHTTPTrigger.yaml new file mode 100644 index 00000000000..44b0e9e0ef0 --- /dev/null +++ b/checkov/terraform/checks/graph_checks/gcp/CloudFunctionSecureHTTPTrigger.yaml @@ -0,0 +1,11 @@ +metadata: + id: "CKV2_GCP_10" + name: "Ensure GCP Cloud Function HTTP trigger is secured" + category: "NETWORKING" +definition: + cond_type: "attribute" + resource_types: + - "google_cloudfunctions_function" + attribute: "https_trigger_security_level" + operator: "equals" + value: "SECURE_ALWAYS" \ No newline at end of file diff --git a/checkov/terraform/checks/graph_checks/gcp/GCRContainerVulnerabilityScanningEnabled.yaml b/checkov/terraform/checks/graph_checks/gcp/GCRContainerVulnerabilityScanningEnabled.yaml new file mode 100644 index 00000000000..d5d088e7b07 --- /dev/null +++ b/checkov/terraform/checks/graph_checks/gcp/GCRContainerVulnerabilityScanningEnabled.yaml @@ -0,0 +1,11 @@ +metadata: + id: "CKV2_GCP_11" + name: "Ensure GCP GCR Container Vulnerability Scanning is enabled" + category: "GENERAL_SECURITY" +definition: + cond_type: "attribute" + resource_types: + - "google_project_services" + attribute: "services" + operator: "contains" + value: "containerscanning.googleapis.com" \ No newline at end of file diff --git a/tests/terraform/graph/checks/resources/CloudFunctionSecureHTTPTrigger/expected.yaml b/tests/terraform/graph/checks/resources/CloudFunctionSecureHTTPTrigger/expected.yaml new file mode 100644 index 00000000000..2c27106e189 --- /dev/null +++ b/tests/terraform/graph/checks/resources/CloudFunctionSecureHTTPTrigger/expected.yaml @@ -0,0 +1,5 @@ +pass: + - "google_cloudfunctions_function.pass" +fail: + - "google_cloudfunctions_function.fail_1" + - "google_cloudfunctions_function.fail_2" diff --git a/tests/terraform/graph/checks/resources/CloudFunctionSecureHTTPTrigger/main.tf b/tests/terraform/graph/checks/resources/CloudFunctionSecureHTTPTrigger/main.tf new file mode 100644 index 00000000000..2511e2ddfc9 --- /dev/null +++ b/tests/terraform/graph/checks/resources/CloudFunctionSecureHTTPTrigger/main.tf @@ -0,0 +1,49 @@ +resource "google_cloudfunctions_function" "pass" { + name = "function-test" + description = "My function" + runtime = "nodejs16" + + available_memory_mb = 128 + source_archive_bucket = google_storage_bucket.bucket.name + source_archive_object = google_storage_bucket_object.archive.name + trigger_http = true + https_trigger_security_level = "SECURE_ALWAYS" + timeout = 60 + entry_point = "helloGET" + labels = { + my-label = "my-label-value" + } +} + +resource "google_cloudfunctions_function" "fail_1" { + name = "function-test" + description = "My function" + runtime = "nodejs16" + + available_memory_mb = 128 + source_archive_bucket = google_storage_bucket.bucket.name + source_archive_object = google_storage_bucket_object.archive.name + trigger_http = true + https_trigger_security_level = "SECURE_OPTIONAL" + timeout = 60 + entry_point = "helloGET" + labels = { + my-label = "my-label-value" + } +} + +resource "google_cloudfunctions_function" "fail_2" { + name = "function-test" + description = "My function" + runtime = "nodejs16" + + available_memory_mb = 128 + source_archive_bucket = google_storage_bucket.bucket.name + source_archive_object = google_storage_bucket_object.archive.name + trigger_http = true + timeout = 60 + entry_point = "helloGET" + labels = { + my-label = "my-label-value" + } +} \ No newline at end of file diff --git a/tests/terraform/graph/checks/resources/EC2InstanceHasIAMRoleAttached/expected.yaml b/tests/terraform/graph/checks/resources/EC2InstanceHasIAMRoleAttached/expected.yaml new file mode 100644 index 00000000000..6cdf8dc4c6e --- /dev/null +++ b/tests/terraform/graph/checks/resources/EC2InstanceHasIAMRoleAttached/expected.yaml @@ -0,0 +1,4 @@ +pass: + - "aws_instance.pass" +fail: + - "aws_instance.fail" diff --git a/tests/terraform/graph/checks/resources/EC2InstanceHasIAMRoleAttached/main.tf b/tests/terraform/graph/checks/resources/EC2InstanceHasIAMRoleAttached/main.tf new file mode 100644 index 00000000000..00f37d9988c --- /dev/null +++ b/tests/terraform/graph/checks/resources/EC2InstanceHasIAMRoleAttached/main.tf @@ -0,0 +1,28 @@ +resource "aws_instance" "pass" { + ami = "ami-005e54dee72cc1d00" # us-west-2 + instance_type = "t2.micro" + iam_instance_profile = "test" + + network_interface { + network_interface_id = aws_network_interface.foo.id + device_index = 0 + } + + credit_specification { + cpu_credits = "unlimited" + } +} + +resource "aws_instance" "fail" { + ami = "ami-005e54dee72cc1d00" + instance_type = "t2.micro" + + network_interface { + network_interface_id = aws_network_interface.foo.id + device_index = 0 + } + + credit_specification { + cpu_credits = "unlimited" + } +} \ No newline at end of file diff --git a/tests/terraform/graph/checks/resources/GCRContainerVulnerabilityScanningEnabled/expected.yaml b/tests/terraform/graph/checks/resources/GCRContainerVulnerabilityScanningEnabled/expected.yaml new file mode 100644 index 00000000000..d5036eb79b6 --- /dev/null +++ b/tests/terraform/graph/checks/resources/GCRContainerVulnerabilityScanningEnabled/expected.yaml @@ -0,0 +1,4 @@ +pass: + - "google_project_services.pass_1" +fail: + - "google_project_services.fail_1" diff --git a/tests/terraform/graph/checks/resources/GCRContainerVulnerabilityScanningEnabled/main.tf b/tests/terraform/graph/checks/resources/GCRContainerVulnerabilityScanningEnabled/main.tf new file mode 100644 index 00000000000..e61a17164f2 --- /dev/null +++ b/tests/terraform/graph/checks/resources/GCRContainerVulnerabilityScanningEnabled/main.tf @@ -0,0 +1,9 @@ +resource "google_project_services" "pass_1" { + project = "your-project-id" + services = ["iam.googleapis.com", "cloudresourcemanager.googleapis.com", "containerscanning.googleapis.com"] +} + +resource "google_project_services" "fail_1" { + project = "your-project-id" + services = ["iam.googleapis.com", "cloudresourcemanager.googleapis.com"] +} diff --git a/tests/terraform/graph/checks/test_yaml_policies.py b/tests/terraform/graph/checks/test_yaml_policies.py index f67842510ca..ac7d5011cf4 100644 --- a/tests/terraform/graph/checks/test_yaml_policies.py +++ b/tests/terraform/graph/checks/test_yaml_policies.py @@ -47,6 +47,9 @@ def test_GuardDutyIsEnabled(self): def test_SGAttachedToResource(self): self.go("SGAttachedToResource") + def test_EC2InstanceHasIAMRoleAttached(self): + self.go("EC2InstanceHasIAMRoleAttached") + def test_StorageContainerActivityLogsNotPublic(self): self.go("StorageContainerActivityLogsNotPublic") @@ -86,6 +89,9 @@ def test_DisableAccessToSqlDBInstanceForRootUsersWithoutPassword(self): def test_GCPProjectHasNoLegacyNetworks(self): self.go("GCPProjectHasNoLegacyNetworks") + def test_GCRContainerVulnerabilityScanningEnabled(self): + self.go("GCRContainerVulnerabilityScanningEnabled") + def test_AzureDataFactoriesEncryptedWithCustomerManagedKey(self): self.go("AzureDataFactoriesEncryptedWithCustomerManagedKey") @@ -104,6 +110,9 @@ def test_ALBRedirectsHTTPToHTTPS(self): def test_GCPLogBucketsConfiguredUsingLock(self): self.go("GCPLogBucketsConfiguredUsingLock") + def test_CloudFunctionSecureHTTPTrigger(self): + self.go("CloudFunctionSecureHTTPTrigger") + def test_GCPAuditLogsConfiguredForAllServicesAndUsers(self): self.go("GCPAuditLogsConfiguredForAllServicesAndUsers")