Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"severity": "HIGH",
"category": "Encryption",
"descriptionText": "Cloud SQL Database Instance should have SSL enabled",
"descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/sql_database_instance#require_ssl",
"descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/sql_database_instance#ssl_mode-1",
"platform": "Terraform",
"descriptionID": "8983549e",
"cloudProvider": "gcp",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package Cx
import data.generic.common as common_lib
import data.generic.terraform as tf_lib

allowed_ssl_modes := ["ENCRYPTED_ONLY", "TRUSTED_CLIENT_CERTIFICATE_REQUIRED"]

CxPolicy[result] {
settings := input.document[i].resource.google_sql_database_instance[name].settings

Expand All @@ -17,7 +19,7 @@ CxPolicy[result] {
"keyExpectedValue": "'settings.ip_configuration' should be defined and not null",
"keyActualValue": "'settings.ip_configuration' is undefined or null",
"searchLine": common_lib.build_search_line(["resource", "google_sql_database_instance", name],["settings"]),
"remediation": "ip_configuration {\n\t\trequire_ssl = true\n\t}\n",
"remediation": sprintf("ip_configuration {\n\t\tssl_mode = %s\n\t}\n", [get_remediation(input.document[i].resource.google_sql_database_instance[name].database_version)]),
"remediationType": "addition",
}
}
Expand All @@ -26,6 +28,7 @@ CxPolicy[result] {
settings := input.document[i].resource.google_sql_database_instance[name].settings
ip_configuration := settings.ip_configuration

not common_lib.valid_key(ip_configuration, "ssl_mode")
not common_lib.valid_key(ip_configuration, "require_ssl")

result := {
Expand All @@ -34,15 +37,39 @@ CxPolicy[result] {
"resourceName": tf_lib.get_resource_name(input.document[i].resource.google_sql_database_instance[name].settings, name),
"searchKey": sprintf("google_sql_database_instance[%s].settings.ip_configuration", [name]),
"issueType": "MissingAttribute",
"keyExpectedValue": "'settings.ip_configuration.require_ssl' should be defined and not null",
"keyActualValue": "'settings.ip_configuration.require_ssl' is undefined or null",
"keyExpectedValue": "'settings.ip_configuration.ssl_mode' should be defined and not null",
"keyActualValue": "'settings.ip_configuration.ssl_mode' is undefined or null",
"searchLine": common_lib.build_search_line(["resource", "google_sql_database_instance", name],["settings", "ip_configuration"]),
"remediation": "require_ssl = true",
"remediation": sprintf("ssl_mode = %s", [get_remediation(input.document[i].resource.google_sql_database_instance[name].database_version)]),
"remediationType": "addition",
}
}

CxPolicy[result] {
resource := input.document[i].resource.google_sql_database_instance[name]
settings := resource.settings

database_version := input.document[i].resource.google_sql_database_instance[name].database_version
kev := get_expected_key(database_version, settings.ip_configuration.ssl_mode)

result := {
"documentId": input.document[i].id,
"resourceType": "google_sql_database_instance",
"resourceName": tf_lib.get_resource_name(input.document[i].resource.google_sql_database_instance[name].settings, name),
"searchKey": sprintf("google_sql_database_instance[%s].settings.ip_configuration.ssl_mode", [name]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("'settings.ip_configuration.ssl_mode' should be set to %s", [kev]),
"keyActualValue": sprintf("'settings.ip_configuration.ssl_mode' is set to '%s'", [settings.ip_configuration.ssl_mode]),
"searchLine": common_lib.build_search_line(["resource", "google_sql_database_instance", name],["settings", "ip_configuration", "ssl_mode"]),
"remediation": json.marshal({
"before": settings.ip_configuration.ssl_mode,
"after": get_remediation(database_version)
}),
"remediationType": "replacement",
}
}

CxPolicy[result] { # legacy support (terraform version < 6.0.1)
settings := input.document[i].resource.google_sql_database_instance[name].settings

settings.ip_configuration.require_ssl == false
Expand All @@ -63,3 +90,14 @@ CxPolicy[result] {
"remediationType": "replacement",
}
}

get_expected_key(database_version, ssl_mode) = "'ENCRYPTED_ONLY'" {
contains(database_version, "SQLSERVER")
ssl_mode != "ENCRYPTED_ONLY"
} else = "'ENCRYPTED_ONLY' or 'TRUSTED_CLIENT_CERTIFICATE_REQUIRED'" {
not common_lib.inArray(allowed_ssl_modes, ssl_mode)
}

get_remediation(database_version) = "ENCRYPTED_ONLY" {
contains(database_version, "SQLSERVER")
} else = "TRUSTED_CLIENT_CERTIFICATE_REQUIRED"
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
resource "google_sql_database_instance" "negative1" {
resource "google_sql_database_instance" "negative1_1" { # legacy support (terraform version < 6.0.1)
provider = google-beta

name = "private-instance-${random_id.db_name_suffix.hex}"
database_version = "POSTGRES_15"
region = "us-central1"

depends_on = [google_service_networking_connection.private_vpc_connection]
Expand All @@ -11,7 +12,7 @@ resource "google_sql_database_instance" "negative1" {
ip_configuration {
ipv4_enabled = false
private_network = google_compute_network.private_network.id
require_ssl = true
require_ssl = true
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
resource "google_sql_database_instance" "negative2_1" {
name = "private-instance-encrypted"
database_version = "POSTGRES_15"
region = "us-central1"

depends_on = [google_service_networking_connection.private_vpc_connection]

settings {
tier = "db-f1-micro"

ip_configuration {
ipv4_enabled = false
private_network = google_compute_network.private_network.id
ssl_mode = "ENCRYPTED_ONLY" # Only allows connections encrypted with SSL/TLS
}
}
}

resource "google_sql_database_instance" "negative2_2" {
name = "private-instance-trusted-cert"
database_version = "POSTGRES_15"
region = "us-central1"

depends_on = [google_service_networking_connection.private_vpc_connection]

settings {
tier = "db-f1-micro"

ip_configuration {
ipv4_enabled = false
private_network = google_compute_network.private_network.id
ssl_mode = "TRUSTED_CLIENT_CERTIFICATE_REQUIRED" # Only allow connections encrypted with SSL/TLS and with valid client certificates
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
resource "google_sql_database_instance" "negative3_1" {
name = "private-instance-encrypted"
database_version = "SQLSERVER_2017_STANDARD"
region = "us-central1"

depends_on = [google_service_networking_connection.private_vpc_connection]

settings {
tier = "db-f1-micro"

ip_configuration {
ipv4_enabled = false
private_network = google_compute_network.private_network.id
ssl_mode = "ENCRYPTED_ONLY" # Only allows connections encrypted with SSL/TLS
}
}
}
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
resource "google_sql_database_instance" "positive1" {
resource "google_sql_database_instance" "positive1_1" { # legacy support (terraform version < 6.0.1)
provider = google-beta

name = "private-instance-${random_id.db_name_suffix.hex}"
database_version = "POSTGRES_15"
region = "us-central1"

depends_on = [google_service_networking_connection.private_vpc_connection]

settings {
tier = "db-f1-micro"
tier = "db-f1-micro" # Undefined "ip_configuration"
}
}

resource "google_sql_database_instance" "positive2" {
resource "google_sql_database_instance" "positive1_2" { # legacy support (terraform version < 6.0.1)
provider = google-beta

name = "private-instance-${random_id.db_name_suffix.hex}"
database_version = "POSTGRES_15"
region = "us-central1"

depends_on = [google_service_networking_connection.private_vpc_connection]
Expand All @@ -24,14 +26,16 @@ resource "google_sql_database_instance" "positive2" {
ip_configuration {
ipv4_enabled = false
private_network = google_compute_network.private_network.id
# Undefined "require_ssl"
}
}
}

resource "google_sql_database_instance" "positive3" {
resource "google_sql_database_instance" "positive1_3" { # legacy support (terraform version < 6.0.1)
provider = google-beta

name = "private-instance-${random_id.db_name_suffix.hex}"
database_version = "POSTGRES_15"
region = "us-central1"

depends_on = [google_service_networking_connection.private_vpc_connection]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@

resource "google_sql_database_instance" "positive2_1" {
name = "private-instance-no-ssl-mode"
database_version = "POSTGRES_15"
region = "us-central1"

depends_on = [google_service_networking_connection.private_vpc_connection]

settings {
tier = "db-f1-micro"

ip_configuration {
ipv4_enabled = false
private_network = google_compute_network.private_network.id
# Undefined "ssl_mode"
}
}
}

resource "google_sql_database_instance" "positive2_2" {
name = "private-instance-unspecified"
database_version = "POSTGRES_15"
region = "us-central1"

depends_on = [google_service_networking_connection.private_vpc_connection]

settings {
tier = "db-f1-micro"

ip_configuration {
ipv4_enabled = false
private_network = google_compute_network.private_network.id
ssl_mode = "SSL_MODE_UNSPECIFIED" # Unexpected value
}
}
}

resource "google_sql_database_instance" "positive2_3" {
name = "private-instance-unencrypted"
database_version = "POSTGRES_15"
region = "us-central1"

depends_on = [google_service_networking_connection.private_vpc_connection]

settings {
tier = "db-f1-micro"

ip_configuration {
ipv4_enabled = false
private_network = google_compute_network.private_network.id
ssl_mode = "ALLOW_UNENCRYPTED_AND_ENCRYPTED" # Allows unencrypted (non-SSL/non-TLS) connections
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
resource "google_sql_database_instance" "positive3_1" {
provider = google-beta

name = "private-instance-${random_id.db_name_suffix.hex}"
database_version = "POSTGRES_15"
region = "us-central1"

depends_on = [google_service_networking_connection.private_vpc_connection]

settings {
tier = "db-f1-micro" # Undefined "ip_configuration"
}
}

resource "google_sql_database_instance" "positive3_2" {
name = "private-instance-no-ssl-mode"
database_version = "SQLSERVER_2017_STANDARD"
region = "us-central1"

depends_on = [google_service_networking_connection.private_vpc_connection]

settings {
tier = "db-f1-micro"

ip_configuration {
ipv4_enabled = false
private_network = google_compute_network.private_network.id
# Undefined "ssl_mode"
}
}
}

resource "google_sql_database_instance" "positive3_3" {
name = "private-instance-unspecified"
database_version = "SQLSERVER_2017_STANDARD"
region = "us-central1"

depends_on = [google_service_networking_connection.private_vpc_connection]

settings {
tier = "db-f1-micro"

ip_configuration {
ipv4_enabled = false
private_network = google_compute_network.private_network.id
ssl_mode = "SSL_MODE_UNSPECIFIED" # Unexpected value
}
}
}

resource "google_sql_database_instance" "positive3_4" {
name = "private-instance-unencrypted"
database_version = "SQLSERVER_2017_STANDARD"
region = "us-central1"

depends_on = [google_service_networking_connection.private_vpc_connection]

settings {
tier = "db-f1-micro"

ip_configuration {
ipv4_enabled = false
private_network = google_compute_network.private_network.id
ssl_mode = "ALLOW_UNENCRYPTED_AND_ENCRYPTED" # Allows unencrypted (non-SSL/non-TLS) connections
}
}
}

resource "google_sql_database_instance" "positive3_5" {
name = "private-instance-unspecified"
database_version = "SQLSERVER_2017_STANDARD"
region = "us-central1"

depends_on = [google_service_networking_connection.private_vpc_connection]

settings {
tier = "db-f1-micro"

ip_configuration {
ipv4_enabled = false
private_network = google_compute_network.private_network.id
ssl_mode = "TRUSTED_CLIENT_CERTIFICATE_REQUIRED" # Value Unsupported by SQLSERVER databases
}
}
}
Loading
Loading