Repository: aquasecurity/tfsec
Pull request #982 (2021-07-30 14:30:51)

Add test for missing rule imports


Patch:
diff --git a/internal/app/tfsec/rules/google/sql/enable_pg_temp_file_logging_rule.go b/internal/app/tfsec/rules/google/sql/enable_pg_temp_file_logging_rule.go
index ea3e825f6..ebe6f9767 100644
--- a/internal/app/tfsec/rules/google/sql/enable_pg_temp_file_logging_rule.go
+++ b/internal/app/tfsec/rules/google/sql/enable_pg_temp_file_logging_rule.go
@@ -47,7 +47,10 @@ resource "google_sql_database_instance" "db" {
 	}
 }
 			`},
-			Links: []string{"https://postgresqlco.nf/doc/en/param/log_temp_files/"},
+			Links: []string{
+				"https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/sql_database_instance",
+				"https://postgresqlco.nf/doc/en/param/log_temp_files/",
+			},
 		},
 		Provider:        provider.GoogleProvider,
 		RequiredTypes:   []string{"resource"},
diff --git a/internal/app/tfsec/rules/google/sql/encrypt_in_transit_data_rule.go b/internal/app/tfsec/rules/google/sql/encrypt_in_transit_data_rule.go
index 9354dee87..61e7be0ae 100644
--- a/internal/app/tfsec/rules/google/sql/encrypt_in_transit_data_rule.go
+++ b/internal/app/tfsec/rules/google/sql/encrypt_in_transit_data_rule.go
@@ -21,10 +21,10 @@ func init() {
 		Service:   "sql",
 		ShortCode: "encrypt-in-transit-data",
 		Documentation: rule.RuleDocumentation{
-			Summary: "SSL connections to a SQL database instance should be enforced.",
-			Explanation: `	`,
-			Impact:     "Intercepted data can be read in transit",
-			Resolution: "Enforce SSL for all connections",
+			Summary:     "SSL connections to a SQL database instance should be enforced.",
+			Explanation: `In-transit data should be encrypted so that if traffic is intercepted data will not be exposed in plaintext to attackers.`,
+			Impact:      "Intercepted data can be read in transit",
+			Resolution:  "Enforce SSL for all connections",
 			BadExample: []string{`
 resource "google_sql_database_instance" "postgres" {
 	name             = "postgres-instance-a"
@@ -63,7 +63,10 @@ resource "google_sql_database_instance" "postgres" {
 	}
 }
 			`},
-			Links: []string{"https://cloud.google.com/sql/docs/mysql/configure-ssl-instance"},
+			Links: []string{
+				"https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/sql_database_instance",
+				"https://cloud.google.com/sql/docs/mysql/configure-ssl-instance",
+			},
 		},
 		Provider:        provider.GoogleProvider,
 		RequiredTypes:   []string{"resource"},
diff --git a/internal/app/tfsec/rules/google/sql/no_contained_db_auth_rule.go b/internal/app/tfsec/rules/google/sql/no_contained_db_auth_rule.go
index 4e5a37167..c03e81599 100644
--- a/internal/app/tfsec/rules/google/sql/no_contained_db_auth_rule.go
+++ b/internal/app/tfsec/rules/google/sql/no_contained_db_auth_rule.go
@@ -45,7 +45,10 @@ resource "google_sql_database_instance" "db" {
 	}
 }
 			`},
-			Links: []string{"https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/contained-database-authentication-server-configuration-option?view=sql-server-ver15"},
+			Links: []string{
+				"https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/sql_database_instance",
+				"https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/contained-database-authentication-server-configuration-option?view=sql-server-ver15",
+			},
 		},
 		Provider:        provider.GoogleProvider,
 		RequiredTypes:   []string{"resource"},
diff --git a/internal/app/tfsec/rules/google/sql/no_cross_db_ownership_chaining_rule.go b/internal/app/tfsec/rules/google/sql/no_cross_db_ownership_chaining_rule.go
index 6d17b8692..748f22af5 100644
--- a/internal/app/tfsec/rules/google/sql/no_cross_db_ownership_chaining_rule.go
+++ b/internal/app/tfsec/rules/google/sql/no_cross_db_ownership_chaining_rule.go
@@ -45,7 +45,10 @@ resource "google_sql_database_instance" "db" {
 	}
 }
 			`},
-			Links: []string{"https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/cross-db-ownership-chaining-server-configuration-option?view=sql-server-ver15"},
+			Links: []string{
+				"https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/sql_database_instance",
+				"https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/cross-db-ownership-chaining-server-configuration-option?view=sql-server-ver15",
+			},
 		},
 		Provider:        provider.GoogleProvider,
 		RequiredTypes:   []string{"resource"},
diff --git a/internal/app/tfsec/rules/google/sql/no_public_access_rule.go b/internal/app/tfsec/rules/google/sql/no_public_access_rule.go
index a4b4ff9dc..2e37c712a 100644
--- a/internal/app/tfsec/rules/google/sql/no_public_access_rule.go
+++ b/internal/app/tfsec/rules/google/sql/no_public_access_rule.go
@@ -22,10 +22,10 @@ func init() {
 		Service:   "sql",
 		ShortCode: "no-public-access",
 		Documentation: rule.RuleDocumentation{
-			Summary: "Ensure that Cloud SQL Database Instances are not publicly exposed",
-			Explanation: `	`,
-			Impact:     "Public exposure of sensitive data",
-			Resolution: "Remove public access from database instances",
+			Summary:     "Ensure that Cloud SQL Database Instances are not publicly exposed",
+			Explanation: `Database instances should be configured so that they are not available over the public internet, but to internal compute resources which access them.`,
+			Impact:      "Public exposure of sensitive data",
+			Resolution:  "Remove public access from database instances",
 			BadExample: []string{`
 resource "google_sql_database_instance" "postgres" {
 	name             = "postgres-instance-a"
@@ -67,7 +67,10 @@ resource "google_sql_database_instance" "postgres" {
 	}
 }
 			`},
-			Links: []string{"https://www.cloudconformity.com/knowledge-base/gcp/CloudSQL/publicly-accessible-cloud-sql-instances.html#"},
+			Links: []string{
+				"https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/sql_database_instance",
+				"https://www.cloudconformity.com/knowledge-base/gcp/CloudSQL/publicly-accessible-cloud-sql-instances.html",
+			},
 		},
 		Provider:        provider.GoogleProvider,
 		RequiredTypes:   []string{"resource"},
diff --git a/internal/app/tfsec/rules/init.go b/internal/app/tfsec/rules/init.go
index cdd805cac..a5c46c1e1 100644
--- a/internal/app/tfsec/rules/init.go
+++ b/internal/app/tfsec/rules/init.go
@@ -10,7 +10,9 @@ import (
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/cloudwatch"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/codebuild"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/config"
+	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/documentdb"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/dynamodb"
+	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/ebs"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/ec2"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/ecr"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/ecs"
@@ -25,8 +27,11 @@ import (
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/kinesis"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/kms"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/lambda"
+	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/launch"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/misc"
+	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/mq"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/msk"
+	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/neptune"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/rds"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/redshift"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/s3"
@@ -56,6 +61,7 @@ import (
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/google/compute"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/google/gke"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/google/iam"
+	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/google/sql"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/google/storage"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/openstack/compute"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/openstack/fw"


Test patch:
diff --git a/internal/app/tfsec/test/init_test.go b/internal/app/tfsec/test/init_test.go
index a8f47a4ab..ee0d56fa2 100644
--- a/internal/app/tfsec/test/init_test.go
+++ b/internal/app/tfsec/test/init_test.go
@@ -1,3 +1,61 @@
 package test
 
-import _ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules"
+import (
+	"fmt"
+	"io/ioutil"
+	"os"
+	"path/filepath"
+	"strings"
+	"testing"
+
+	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules"
+)
+
+func Test_AllRulesWereInitialised(t *testing.T) {
+	rulesDir, err := filepath.Abs(strings.ReplaceAll("../rules", "/", string(os.PathSeparator)))
+	if err != nil {
+		t.Fatal(err)
+	}
+	initData, err := ioutil.ReadFile(filepath.Join(rulesDir, "init.go"))
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	packages, err := findPackages(rulesDir)
+	if err != nil {
+		t.Fatal(err)
+	}
+	for _, pkg := range packages {
+		fullPath := fmt.Sprintf("github.com/aquasecurity/tfsec/internal/app/tfsec/rules/%s", pkg)
+		if !strings.Contains(string(initData), `"`+fullPath+`"`) {
+			t.Errorf("init.go does not contain the rule package '%s'", fullPath)
+		}
+	}
+
+}
+
+func findPackages(dir string) ([]string, error) {
+
+	packages := make(map[string]struct{})
+	if err := filepath.Walk(dir, func(path string, f os.FileInfo, err error) error {
+		if f.IsDir() {
+			return err
+		}
+		if filepath.Base(path) == "init.go" {
+			return err
+		}
+		sub := filepath.Dir(path)
+		packages[filepath.Base(filepath.Dir(sub))+"/"+filepath.Base(sub)] = struct{}{}
+		return err
+	}); err != nil {
+		return nil, err
+	}
+
+	var packageList []string
+
+	for pkg := range packages {
+		packageList = append(packageList, pkg)
+	}
+
+	return packageList, nil
+}