Repository: aquasecurity/tfsec
Pull request #928 (2021-07-22 10:53:54)

Added check for postgres temporary file logging


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
new file mode 100644
index 000000000..854b76403
--- /dev/null
+++ b/internal/app/tfsec/rules/google/sql/enable_pg_temp_file_logging_rule.go
@@ -0,0 +1,100 @@
+package sql
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/aquasecurity/tfsec/pkg/result"
+	"github.com/aquasecurity/tfsec/pkg/severity"
+
+	"github.com/aquasecurity/tfsec/pkg/provider"
+
+	"github.com/aquasecurity/tfsec/internal/app/tfsec/hclcontext"
+
+	"github.com/aquasecurity/tfsec/internal/app/tfsec/block"
+
+	"github.com/aquasecurity/tfsec/pkg/rule"
+
+	"github.com/aquasecurity/tfsec/internal/app/tfsec/scanner"
+)
+
+func init() {
+	scanner.RegisterCheckRule(rule.Rule{
+		Service:   "sql",
+		ShortCode: "enable-pg-temp-file-logging",
+		Documentation: rule.RuleDocumentation{
+			Summary:     "Temporary file logging should be enabled for all temporary files.",
+			Explanation: "Temporary files are not logged by default. To log all temporary files, a value of `0` should set in the `log_temp_files` flag - as all files greater in size than the number of bytes set in this flag will be logged.",
+			Impact:      "Use of temporary files will not be logged",
+			Resolution:  "Enable temporary file logging for all files",
+			BadExample: `
+resource "google_sql_database_instance" "db" {
+	name             = "db"
+	database_version = "POSTGRES_12"
+	region           = "us-central1"
+}
+			`,
+			GoodExample: `
+resource "google_sql_database_instance" "db" {
+	name             = "db"
+	database_version = "POSTGRES_12"
+	region           = "us-central1"
+	settings {
+	    database_flags {
+		    name  = "log_temp_files"
+		    value = "0"
+		}
+	}
+}
+			`,
+			Links: []string{"https://postgresqlco.nf/doc/en/param/log_temp_files/"},
+		},
+		Provider:        provider.GoogleProvider,
+		RequiredTypes:   []string{"resource"},
+		RequiredLabels:  []string{"google_sql_database_instance"},
+		DefaultSeverity: severity.Medium,
+		CheckFunc: func(set result.Set, resourceBlock block.Block, _ *hclcontext.Context) {
+
+			dbVersionAttr := resourceBlock.GetAttribute("database_version")
+			if dbVersionAttr != nil && dbVersionAttr.IsString() && !strings.HasPrefix(dbVersionAttr.Value().AsString(), "POSTGRES") {
+				return
+			}
+
+			settingsBlock := resourceBlock.GetBlock("settings")
+			if settingsBlock == nil {
+				set.Add(
+					result.New(resourceBlock).
+						WithDescription(fmt.Sprintf("Resource '%s' has temporary file logging disabled by default", resourceBlock.FullName())),
+				)
+				return
+			}
+
+			for _, dbFlagBlock := range settingsBlock.GetBlocks("database_flags") {
+				if nameAttr := dbFlagBlock.GetAttribute("name"); nameAttr != nil && nameAttr.IsString() && nameAttr.Value().AsString() == "log_temp_files" {
+					if valueAttr := dbFlagBlock.GetAttribute("value"); valueAttr != nil && valueAttr.IsString() {
+						if valueAttr.Value().AsString() == "-1" {
+							set.Add(
+								result.New(resourceBlock).
+									WithDescription(fmt.Sprintf("Resource '%s' has temporary file logging explicitly disabled", resourceBlock.FullName())),
+							)
+						} else if valueAttr.Value().AsString() != "0" {
+							set.Add(
+								result.New(resourceBlock).
+									WithDescription(fmt.Sprintf("Resource '%s' has temporary file logging disabled for files of certain sizes", resourceBlock.FullName())),
+							)
+						}
+						// otherwise it's off, awesome
+						return
+					}
+				}
+			}
+
+			// we didn't find the flag so it must be on by default
+			set.Add(
+				result.New(resourceBlock).
+					WithDescription(fmt.Sprintf("Resource '%s' has temporary file logging disabled by default", resourceBlock.FullName())),
+			)
+
+		},
+	})
+}


Test patch:
diff --git a/internal/app/tfsec/rules/google/sql/enable_pg_temp_file_logging_rule_test.go b/internal/app/tfsec/rules/google/sql/enable_pg_temp_file_logging_rule_test.go
new file mode 100644
index 000000000..6f88c9210
--- /dev/null
+++ b/internal/app/tfsec/rules/google/sql/enable_pg_temp_file_logging_rule_test.go
@@ -0,0 +1,100 @@
+package sql
+
+import (
+	"testing"
+
+	"github.com/aquasecurity/tfsec/internal/app/tfsec/testutil"
+)
+
+func Test_GoogleEnablePgTempFileLogging(t *testing.T) {
+	expectedCode := "google-sql-enable-pg-temp-file-logging"
+
+	var tests = []struct {
+		name                  string
+		source                string
+		mustIncludeResultCode string
+		mustExcludeResultCode string
+	}{
+		{
+			name: "rule matches when flag is not explicitly set (defaults to -1)",
+			source: `
+resource "google_sql_database_instance" "db" {
+	name             = "db"
+	database_version = "POSTGRES_12"
+	region           = "us-central1"
+}
+`,
+			mustIncludeResultCode: expectedCode,
+		},
+		{
+			name: "rule matches when flag is set to '-1'",
+			source: `
+resource "google_sql_database_instance" "db" {
+	name             = "db"
+	database_version = "POSTGRES_12"
+	region           = "us-central1"
+	settings {
+		database_flags {
+			name  = "log_temp_files"
+			value = "-1"
+		}
+	}
+}
+`,
+			mustIncludeResultCode: expectedCode,
+		},
+		{
+			name: "rule matches when flag is set to '512'",
+			source: `
+resource "google_sql_database_instance" "db" {
+	name             = "db"
+	database_version = "POSTGRES_12"
+	region           = "us-central1"
+	settings {
+		database_flags {
+			name  = "log_temp_files"
+			value = "512"
+		}
+	}
+}
+`,
+			mustIncludeResultCode: expectedCode,
+		},
+		{
+			name: "rule does not match when flag is set to '0'",
+			source: `
+resource "google_sql_database_instance" "db" {
+	name             = "db"
+	database_version = "POSTGRES_12"
+	region           = "us-central1"
+	settings {
+		database_flags {
+			name  = "log_temp_files"
+			value = "0"
+		}
+	}
+}
+`,
+			mustExcludeResultCode: expectedCode,
+		},
+		{
+			name: "rule does not match when postgres is not used",
+			source: `
+resource "google_sql_database_instance" "db" {
+	name             = "db"
+	database_version = "MYSQL_8_0"
+	region           = "us-central1"
+}
+`,
+			mustExcludeResultCode: expectedCode,
+		},
+	}
+
+	for _, test := range tests {
+		t.Run(test.name, func(t *testing.T) {
+
+			results := testutil.ScanHCL(test.source, t)
+			testutil.AssertCheckCode(t, test.mustIncludeResultCode, test.mustExcludeResultCode, results)
+		})
+	}
+}
diff --git a/internal/app/tfsec/rules/google/sql/no_contained_db_auth_rule_test.go b/internal/app/tfsec/rules/google/sql/no_contained_db_auth_rule_test.go
index 4f33c8e70..c59feb86b 100644
--- a/internal/app/tfsec/rules/google/sql/no_contained_db_auth_rule_test.go
+++ b/internal/app/tfsec/rules/google/sql/no_contained_db_auth_rule_test.go
@@ -16,7 +16,7 @@ func Test_GoogleNoContainedDbAuth(t *testing.T) {
 		mustExcludeResultCode string
 	}{
 		{
-			name: "TODO: add test name",
+			name: "rule matches when contained db auth defaults to enabled",
 			source: `
 resource "google_sql_database_instance" "db" {
 	name             = "db"
@@ -27,7 +27,7 @@ resource "google_sql_database_instance" "db" {
 			mustIncludeResultCode: expectedCode,
 		},
 		{
-			name: "TODO: add test name",
+			name: "rule does not match when contained auth is disabled",
 			source: `
 resource "google_sql_database_instance" "db" {
 	name             = "db"