Skip to content

Commit 359b414

Browse files
feat(query): implements "Beta - Blob Storage Without Soft Delete" (#7831)
* implements a query to ensure that resources of type "azurerm_storage_account" configure a value of 7 to 365 on their "blob_properties.delete_retention_policy.days" field.
1 parent 5922f80 commit 359b414

File tree

6 files changed

+147
-0
lines changed

6 files changed

+147
-0
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"id": "056d28cc-7ee9-4b12-b2d1-16b7b66db72d",
3+
"queryName": "Beta - Blob Storage Without Soft Delete",
4+
"severity": "HIGH",
5+
"category": "Backup",
6+
"descriptionText": "All 'azurerm_storage_account' resources should define a 'delete_retention_policy' block for their 'blob_properties' to allow data recovery",
7+
"descriptionUrl": "https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/storage_account#delete_retention_policy-2",
8+
"platform": "Terraform",
9+
"descriptionID": "056d28cc",
10+
"cloudProvider": "azure",
11+
"cwe": "754",
12+
"riskScore": "6.0",
13+
"experimental": "true"
14+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
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.azurerm_storage_account[name]
8+
9+
results := get_results(resource, name)
10+
11+
result := {
12+
"documentId": input.document[i].id,
13+
"resourceType": "azurerm_storage_account",
14+
"resourceName": tf_lib.get_resource_name(resource, name),
15+
"searchKey": results.searchKey,
16+
"issueType": results.issueType,
17+
"keyExpectedValue": results.keyExpectedValue,
18+
"keyActualValue": results.keyActualValue,
19+
"searchLine": results.searchLine
20+
}
21+
}
22+
23+
get_results(resource, name) = results {
24+
not common_lib.valid_key(resource, "blob_properties")
25+
results := {
26+
"searchKey" : sprintf("azurerm_storage_account[%s]", [name]),
27+
"issueType": "MissingAttribute",
28+
"keyExpectedValue": sprintf("'azurerm_storage_account[%s].blob_properties.delete_retention_policy' should be defined and not null", [name]),
29+
"keyActualValue" : sprintf("'azurerm_storage_account[%s].blob_properties' is undefined or null", [name]),
30+
"searchLine" : common_lib.build_search_line(["resource", "azurerm_storage_account", name], [])
31+
}
32+
} else = results {
33+
not common_lib.valid_key(resource.blob_properties, "delete_retention_policy")
34+
results := {
35+
"searchKey" : sprintf("azurerm_storage_account[%s].blob_properties", [name]),
36+
"issueType": "MissingAttribute",
37+
"keyExpectedValue": sprintf("'azurerm_storage_account[%s].blob_properties.delete_retention_policy' should be defined and not null", [name]),
38+
"keyActualValue" : sprintf("'azurerm_storage_account[%s].blob_properties.delete_retention_policy' is undefined or null", [name]),
39+
"searchLine" : common_lib.build_search_line(["resource", "azurerm_storage_account", name, "blob_properties"], [])
40+
}
41+
} else = results {
42+
resource.blob_properties.delete_retention_policy.days < 7
43+
results := {
44+
"searchKey" : sprintf("azurerm_storage_account[%s].blob_properties.delete_retention_policy.days", [name]),
45+
"issueType": "IncorrectValue",
46+
"keyExpectedValue": sprintf("'azurerm_storage_account[%s].blob_properties.delete_retention_policy.days' should be set to a value higher than '6'", [name]),
47+
"keyActualValue" : sprintf("'azurerm_storage_account[%s].blob_properties.delete_retention_policy.days' is set to '%d'", [name, resource.blob_properties.delete_retention_policy.days]),
48+
"searchLine" : common_lib.build_search_line(["resource", "azurerm_storage_account", name, "blob_properties", "delete_retention_policy", "days"], [])
49+
}
50+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
resource "azurerm_storage_account" "negative1" {
2+
name = "negative1"
3+
resource_group_name = "testRG"
4+
location = "northeurope"
5+
account_tier = "Premium"
6+
account_replication_type = "LRS"
7+
account_kind = "FileStorage"
8+
9+
blob_properties {
10+
delete_retention_policy {
11+
days = 49
12+
}
13+
}
14+
}
15+
16+
resource "azurerm_storage_account" "negative2" {
17+
name = "negative2"
18+
resource_group_name = "testRG"
19+
location = "northeurope"
20+
account_tier = "Premium"
21+
account_replication_type = "LRS"
22+
account_kind = "FileStorage"
23+
24+
blob_properties {
25+
delete_retention_policy {} # defaults to 7 days
26+
}
27+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
resource "azurerm_storage_account" "positive1" {
2+
name = "positive1"
3+
resource_group_name = azurerm_resource_group.positive1.name
4+
location = azurerm_resource_group.positive1.location
5+
account_tier = "Standard"
6+
account_replication_type = "GRS"
7+
8+
# missing "blob_properties"
9+
}
10+
11+
resource "azurerm_storage_account" "positive2" {
12+
name = "positive2"
13+
resource_group_name = azurerm_resource_group.positive2.name
14+
location = azurerm_resource_group.positive2.location
15+
account_tier = "Standard"
16+
account_replication_type = "GRS"
17+
18+
blob_properties {
19+
# missing "delete_retention_policy"
20+
}
21+
}
22+
23+
resource "azurerm_storage_account" "positive3" {
24+
name = "positive3"
25+
resource_group_name = azurerm_resource_group.positive3.name
26+
location = azurerm_resource_group.positive3.location
27+
account_tier = "Standard"
28+
account_replication_type = "GRS"
29+
30+
blob_properties {
31+
delete_retention_policy {
32+
days = 5 # lower than minimum value (7)
33+
}
34+
}
35+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
[
2+
{
3+
"queryName": "Beta - Blob Storage Without Soft Delete",
4+
"severity": "HIGH",
5+
"line": 1
6+
},
7+
{
8+
"queryName": "Beta - Blob Storage Without Soft Delete",
9+
"severity": "HIGH",
10+
"line": 18
11+
},
12+
{
13+
"queryName": "Beta - Blob Storage Without Soft Delete",
14+
"severity": "HIGH",
15+
"line": 32
16+
}
17+
]

assets/similarityID_transition/terraform_azure.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ similarityIDChangeList:
33
queryName: Sensitive Port Is Exposed To Wide Private Network
44
observations: ""
55
change: 5
6+
- queryId: 056d28cc-7ee9-4b12-b2d1-16b7b66db72d
7+
queryName: Beta - Blob Storage Without Soft Delete
8+
observations: ""
9+
change: 2
610
- queryId: 233ab26d-8f17-4dce-9616-41479da9ffe3
711
queryName: Beta - Storage Account Using Unsafe SMB Channel Encryption
812
observations: ""

0 commit comments

Comments
 (0)