Skip to content

Commit cf02a60

Browse files
feat(query): implements "Beta - SQL DB Instance With Local Data Loading Enabled" (#7777)
* query to ensure 'local_infile' flag is disabled for "google_sql_database_instance" resources
1 parent 8b6c399 commit cf02a60

File tree

6 files changed

+243
-0
lines changed

6 files changed

+243
-0
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"id": "51a2c34d-dfd0-436f-aa34-e8f796e052fd",
3+
"queryName": "Beta - SQL DB Instance With Local Data Loading Enabled",
4+
"severity": "MEDIUM",
5+
"category": "Insecure Defaults",
6+
"descriptionText": "All 'google_sql_database_instance' resources based on 'MYSQL' should disable the 'local_infile' flag to prevent unwanted exposure",
7+
"descriptionUrl": "https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/sql_database_instance.html#settings-1",
8+
"platform": "Terraform",
9+
"descriptionID": "51a2c34d",
10+
"cloudProvider": "gcp",
11+
"cwe": "732",
12+
"riskScore": "3.0",
13+
"experimental": "true"
14+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
package Cx
2+
3+
import data.generic.common as common_lib
4+
import data.generic.terraform as tf_lib
5+
6+
CxPolicy[result] {
7+
resource := input.document[i].resource.google_sql_database_instance[name]
8+
9+
contains(resource.database_version, "MYSQL")
10+
results := get_results(resource, name)
11+
12+
result := {
13+
"documentId": input.document[i].id,
14+
"resourceType": "google_sql_database_instance",
15+
"resourceName": tf_lib.get_resource_name(resource, name),
16+
"searchKey": results.searchKey,
17+
"issueType": results.issueType,
18+
"keyExpectedValue": results.keyExpectedValue,
19+
"keyActualValue": results.keyActualValue,
20+
"searchLine": results.searchLine
21+
}
22+
}
23+
24+
get_results(resource, name) = results {
25+
not common_lib.valid_key(resource, "settings")
26+
27+
results := {
28+
"searchKey": sprintf("google_sql_database_instance[%s]", [name]),
29+
"issueType": "MissingAttribute",
30+
"keyExpectedValue": sprintf("'google_sql_database_instance[%s].settings.database_flags' should be defined and set 'local_infile' to 'off'", [name]),
31+
"keyActualValue": sprintf("'google_sql_database_instance[%s].settings' is undefined or null", [name]),
32+
"searchLine": common_lib.build_search_line(["resource", "google_sql_database_instance", name], [])
33+
34+
}
35+
} else = results {
36+
not common_lib.valid_key(resource.settings, "database_flags")
37+
38+
results := {
39+
"searchKey": sprintf("google_sql_database_instance[%s].settings", [name]),
40+
"issueType": "MissingAttribute",
41+
"keyExpectedValue": sprintf("'google_sql_database_instance[%s].settings.database_flags' should be defined and set 'local_infile' to 'off'", [name]),
42+
"keyActualValue": sprintf("'google_sql_database_instance[%s].settings.database_flags' is undefined or null", [name]),
43+
"searchLine": common_lib.build_search_line(["resource", "google_sql_database_instance", name, "settings"], [])
44+
}
45+
46+
} else = results {
47+
not has_flag(resource.settings.database_flags)
48+
49+
results := {
50+
"searchKey": sprintf("google_sql_database_instance[%s].settings.database_flags", [name]),
51+
"issueType": "MissingAttribute",
52+
"keyExpectedValue": sprintf("'google_sql_database_instance[%s].settings.database_flags' should be defined and set 'local_infile' to 'off'", [name]),
53+
"keyActualValue": sprintf("'google_sql_database_instance[%s].settings.database_flags' does not set 'local_infile'", [name]),
54+
"searchLine": common_lib.build_search_line(["resource", "google_sql_database_instance", name, "settings", "database_flags"], [])
55+
}
56+
57+
} else = results { # array
58+
resource.settings.database_flags[x].name == "local_infile"
59+
resource.settings.database_flags[x].value != "off"
60+
61+
results := {
62+
"searchKey": sprintf("google_sql_database_instance[%s].settings.database_flags[%d].name", [name, x]),
63+
"issueType": "IncorrectValue",
64+
"keyExpectedValue": sprintf("'google_sql_database_instance[%s].settings.database_flags' should be defined and set 'local_infile' to 'off'", [name]),
65+
"keyActualValue": sprintf("'google_sql_database_instance[%s].settings.database_flags' sets 'local_infile' to '%s'", [name, resource.settings.database_flags[x].value]),
66+
"searchLine": common_lib.build_search_line(["resource", "google_sql_database_instance", name, "settings", "database_flags", x, "name"], [])
67+
}
68+
} else = results {
69+
resource.settings.database_flags.name == "local_infile"
70+
resource.settings.database_flags.value != "off"
71+
72+
results := {
73+
"searchKey": sprintf("google_sql_database_instance[%s].settings.database_flags.name", [name]),
74+
"issueType": "IncorrectValue",
75+
"keyExpectedValue": sprintf("'google_sql_database_instance[%s].settings.database_flags' should be defined and set 'local_infile' to 'off'", [name]),
76+
"keyActualValue": sprintf("'google_sql_database_instance[%s].settings.database_flags' sets 'local_infile' to '%s'", [name, resource.settings.database_flags.value]),
77+
"searchLine": common_lib.build_search_line(["resource", "google_sql_database_instance", name, "settings", "database_flags", "name"], [])
78+
}
79+
}
80+
81+
has_flag(database_flags) {
82+
database_flags[_].name == "local_infile"
83+
} else {
84+
database_flags.name == "local_infile"
85+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
resource "google_sql_database_instance" "negative_1" {
2+
name = "main-instance"
3+
database_version = "POSTGRES_15" # Is not a MYSQL instance
4+
region = "us-central1"
5+
6+
settings {
7+
tier = "db-f1-micro"
8+
}
9+
}
10+
11+
resource "google_sql_database_instance" "negative_2" {
12+
name = "mysql-instance-with-flag"
13+
database_version = "MYSQL_8_0"
14+
region = "us-central1"
15+
16+
settings {
17+
tier = "db-f1-micro"
18+
19+
database_flags {
20+
name = "sample_flag1"
21+
value = "off"
22+
}
23+
24+
database_flags { # Has flag set to "off"
25+
name = "local_infile"
26+
value = "off"
27+
}
28+
29+
database_flags {
30+
name = "sample_flag2"
31+
value = "off"
32+
}
33+
}
34+
}
35+
36+
resource "google_sql_database_instance" "negative_3" { # Single object support test
37+
name = "mysql-instance-with-flag"
38+
database_version = "MYSQL_8_0"
39+
region = "us-central1"
40+
41+
settings {
42+
tier = "db-f1-micro"
43+
44+
database_flags {
45+
name = "local_infile"
46+
value = "off"
47+
} # Has flag set to "off"
48+
}
49+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
resource "google_sql_database_instance" "positive_1" {
2+
name = "mysql-instance-without-flag"
3+
database_version = "MYSQL_8_0"
4+
region = "us-central1"
5+
6+
# Missing 'settings' field
7+
}
8+
9+
resource "google_sql_database_instance" "positive_2" {
10+
name = "mysql-instance-without-flag"
11+
database_version = "MYSQL_8_0"
12+
region = "us-central1"
13+
14+
settings {} # Missing 'database_flags' field
15+
}
16+
17+
resource "google_sql_database_instance" "positive_3" {
18+
name = "mysql-instance-without-flag"
19+
database_version = "MYSQL_8_0"
20+
region = "us-central1"
21+
22+
settings {
23+
database_flags {
24+
name = "sample_flag1"
25+
value = "off"
26+
} # Missing 'local_infile' flag
27+
}
28+
}
29+
30+
resource "google_sql_database_instance" "positive_4" {
31+
name = "mysql-instance-with-flag"
32+
database_version = "MYSQL_8_0"
33+
region = "us-central1"
34+
35+
settings {
36+
database_flags {
37+
name = "sample_flag1"
38+
value = "off"
39+
}
40+
41+
database_flags { # Flag is not set to "off"
42+
name = "local_infile"
43+
value = "on"
44+
}
45+
46+
database_flags {
47+
name = "sample_flag2"
48+
value = "off"
49+
}
50+
}
51+
}
52+
53+
resource "google_sql_database_instance" "positive_5" { # Single object support test
54+
name = "mysql-instance-with-flag"
55+
database_version = "MYSQL_8_0"
56+
region = "us-central1"
57+
58+
settings {
59+
database_flags {
60+
name = "local_infile"
61+
value = "on"
62+
} # Flag is not set to "off"
63+
}
64+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
[
2+
{
3+
"queryName": "Beta - SQL DB Instance With Local Data Loading Enabled",
4+
"severity": "MEDIUM",
5+
"line": 1
6+
},
7+
{
8+
"queryName": "Beta - SQL DB Instance With Local Data Loading Enabled",
9+
"severity": "MEDIUM",
10+
"line": 14
11+
},
12+
{
13+
"queryName": "Beta - SQL DB Instance With Local Data Loading Enabled",
14+
"severity": "MEDIUM",
15+
"line": 23
16+
},
17+
{
18+
"queryName": "Beta - SQL DB Instance With Local Data Loading Enabled",
19+
"severity": "MEDIUM",
20+
"line": 42
21+
},
22+
{
23+
"queryName": "Beta - SQL DB Instance With Local Data Loading Enabled",
24+
"severity": "MEDIUM",
25+
"line": 60
26+
}
27+
]

assets/similarityID_transition/terraform_gcp.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ similarityIDChangeList:
33
queryName: Beta - Google DNS Policy Logging Disabled
44
observations: ""
55
change: 2
6+
- queryId: 51a2c34d-dfd0-436f-aa34-e8f796e052fd
7+
queryName: Beta - SQL DB Instance With Local Data Loading Enabled
8+
observations: ""
9+
change: 2
610
- queryId: b5b70198-2a34-4792-b0d9-ce99abe485bb
711
queryName: Beta - SQL DB Instance With Exposed Show Privileges
812
observations: ""

0 commit comments

Comments
 (0)