Repository: tfsec/tfsec
Pull request #522 (2020-11-17 17:07:25)

Update GCP006
:wave: Made a small change to GCP006 to account for `google_container_node_pool` resources as well. Both are defined the same way as this value is always within the node_config block. 

Also updated the tests as the original one was a bit lacklustre. 


Patch:
diff --git a/internal/app/tfsec/checks/gcp006.go b/internal/app/tfsec/checks/gcp006.go
index e78310119..ea1d063ee 100644
--- a/internal/app/tfsec/checks/gcp006.go
+++ b/internal/app/tfsec/checks/gcp006.go
@@ -14,21 +14,25 @@ import (
 const GkeNodeMetadataExposed scanner.RuleCode = "GCP006"
 const GkeNodeMetadataExposedDescription scanner.RuleSummary = "Node metadata value disables metadata concealment."
 const GkeNodeMetadataExposedExplanation = `
-If the <code>workflow_metadata_config</code> block is included the the <code>node_metadata</code> attribute is required. 
+If the <code>workload_metadata_config</code> block within <code>node_config</code> is included, the <code>node_metadata</code> attribute should be configured securely.
 
-The attribute should be set to <code>SPECIFIED</code> to ensure that the the VM metadata is not unnecessarily exposed to pods.
+The attribute should be set to <code>SECURE</code> to use metadata concealment, or <code>GKE_METADATA_SERVER</code> if workload identity is enabled. This ensures that the VM metadata is not unnecessarily exposed to pods.
 
 `
 const GkeNodeMetadataExposedBadExample = `
-resource "google_container_cluster" "gke" {
-	workload_metadata_config {
-		node_metadata = "EXPOSE"
+resource "google_container_node_pool" "gke" {
+	node_config {
+		workload_metadata_config {
+			node_metadata = "EXPOSE"
+		}
 	}
 }`
 const GkeNodeMetadataExposedGoodExample = `
-resource "google_container_cluster" "gke" {
-	workload_metadata_config {
-		node_metadata = "SPECIFIED"
+resource "google_container_node_pool" "gke" {
+	node_config {
+		workload_metadata_config {
+			node_metadata = "SECURE"
+		}
 	}
 }`
 
@@ -47,10 +51,10 @@ func init() {
 		},
 		Provider:       scanner.GCPProvider,
 		RequiredTypes:  []string{"resource"},
-		RequiredLabels: []string{"google_container_cluster"},
+		RequiredLabels: []string{"google_container_cluster", "google_container_node_pool"},
 		CheckFunc: func(check *scanner.Check, block *parser.Block, _ *scanner.Context) []scanner.Result {
 
-			nodeMetadata := block.GetBlock("workload_metadata_config").GetAttribute("node_metadata")
+			nodeMetadata := block.GetBlock("node_config").GetBlock("workload_metadata_config").GetAttribute("node_metadata")
 
 			if nodeMetadata != nil && nodeMetadata.Type() == cty.String &&
 				(nodeMetadata.Value().AsString() == "EXPOSE" || nodeMetadata.Value().AsString() == "UNSPECIFIED") {


Test patch:
diff --git a/internal/app/tfsec/test/gcp006_test.go b/internal/app/tfsec/test/gcp006_test.go
index 43a568e8d..b8a5ea61b 100644
--- a/internal/app/tfsec/test/gcp006_test.go
+++ b/internal/app/tfsec/test/gcp006_test.go
@@ -16,25 +16,101 @@ func Test_GkeNodeMetadataExposed(t *testing.T) {
 		mustExcludeResultCode scanner.RuleCode
 	}{
 		{
-			name: "check google_container_cluster with workload_metadata_config.node_metadata set to EXPOSE",
+			name: "check google_container_cluster with node_config.workload_metadata_config.node_metadata set to EXPOSE",
 			source: `
 resource "google_container_cluster" "gke" {
-	workload_metadata_config {
-		node_metadata = "EXPOSE"
+	node_config {
+		workload_metadata_config {
+			node_metadata = "EXPOSE"
 		}
+	}
 }`,
 			mustIncludeResultCode: checks.GkeNodeMetadataExposed,
 		},
 		{
-			name: "check google_container_cluster with workload_metadata_config.node_metadata set to UNSPECIFIED",
+			name: "check google_container_cluster with node_config.workload_metadata_config.node_metadata set to UNSPECIFIED",
 			source: `
 resource "google_container_cluster" "gke" {
-	workload_metadata_config {
-		node_metadata = "UNSPECIFIED"
+	node_config {
+		workload_metadata_config {
+			node_metadata = "UNSPECIFIED"
 		}
+	}
 }`,
 			mustIncludeResultCode: checks.GkeNodeMetadataExposed,
 		},
+		{
+			name: "check google_container_node_pool with node_config.workload_metadata_config.node_metadata set to EXPOSE",
+			source: `
+resource "google_container_node_pool" "gke" {
+	node_config {
+		workload_metadata_config {
+			node_metadata = "EXPOSE"
+		}
+	}
+}`,
+			mustIncludeResultCode: checks.GkeNodeMetadataExposed,
+		},
+		{
+			name: "check google_container_node_pool with node_config.workload_metadata_config.node_metadata set to UNSPECIFIED",
+			source: `
+resource "google_container_node_pool" "gke" {
+	node_config {
+		workload_metadata_config {
+			node_metadata = "UNSPECIFIED"
+		}
+	}
+}`,
+			mustIncludeResultCode: checks.GkeNodeMetadataExposed,
+		},
+		{
+			name: "check google_container_cluster with node_config.workload_metadata_config.node_metadata set to SECURE",
+			source: `
+resource "google_container_cluster" "gke" {
+	node_config {
+		workload_metadata_config {
+			node_metadata = "SECURE"
+		}
+	}
+}`,
+			mustExcludeResultCode: checks.GkeNodeMetadataExposed,
+		},
+		{
+			name: "check google_container_cluster with node_config.workload_metadata_config.node_metadata set to GKE_METADATA_SERVER",
+			source: `
+resource "google_container_cluster" "gke" {
+	node_config {
+		workload_metadata_config {
+			node_metadata = "GKE_METADATA_SERVER"
+		}
+	}
+}`,
+			mustExcludeResultCode: checks.GkeNodeMetadataExposed,
+		},
+		{
+			name: "check google_container_node_pool with node_config.workload_metadata_config.node_metadata set to SECURE",
+			source: `
+resource "google_container_node_pool" "gke" {
+	node_config {
+		workload_metadata_config {
+			node_metadata = "SECURE"
+		}
+	}
+}`,
+			mustExcludeResultCode: checks.GkeNodeMetadataExposed,
+		},
+		{
+			name: "check google_container_node_pool with node_config.workload_metadata_config.node_metadata set to GKE_METADATA_SERVER",
+			source: `
+resource "google_container_node_pool" "gke" {
+	node_config {
+		workload_metadata_config {
+			node_metadata = "GKE_METADATA_SERVER"
+		}
+	}
+}`,
+			mustExcludeResultCode: checks.GkeNodeMetadataExposed,
+		},
 	}
 
 	for _, test := range tests {