Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,4 @@
"cloudProvider": "azure",
"cwe": "311",
"riskScore": "5.5"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,55 @@ import data.generic.common as common_lib
import data.generic.terraform as tf_lib

CxPolicy[result] {
resource := input.document[i].resource
encryption := resource.azurerm_managed_disk[name]
not common_lib.valid_key(encryption, "encryption_settings")
resource := input.document[i].resource.azurerm_managed_disk[name]

results := undefined_or_empty(resource, name)

result := {
"documentId": input.document[i].id,
"resourceType": "azurerm_managed_disk",
"resourceName": tf_lib.get_resource_name(resource, name),
"searchKey": sprintf("azurerm_managed_disk[%s]", [name]),
"issueType": "MissingAttribute",
"keyExpectedValue": sprintf("azurerm_managed_disk[%s].encryption_settings should be defined and not null", [name]),
"keyActualValue": sprintf("azurerm_managed_disk[%s].encryption_settings is undefined or null", [name]),
"searchLine": common_lib.build_search_line(["resource","azurerm_managed_disk" ,name], []),
"remediation": "encryption_settings = {\n\t\t enabled= true\n\t}\n",
"remediationType": "addition",
"searchKey": results.searchKey,
"issueType": results.issueType,
"keyExpectedValue": results.keyExpectedValue,
"keyActualValue": results.keyActualValue,
"searchLine": results.searchLine,
"remediation": results.remediation,
"remediationType": results.remediationType
}
}

CxPolicy[result] {
resource := input.document[i].resource
encryption := resource.azurerm_managed_disk[name]
encryption.encryption_settings.enabled == false

result := {
"documentId": input.document[i].id,
"resourceType": "azurerm_managed_disk",
"resourceName": tf_lib.get_resource_name(resource, name),
undefined_or_empty(resource, name) = results {
not common_lib.valid_key(resource, "encryption_settings")
results := {
"searchKey": sprintf("azurerm_managed_disk[%s]", [name]),
"issueType": "MissingAttribute",
"keyExpectedValue": sprintf("'azurerm_managed_disk[%s].encryption_settings' should be defined and not null", [name]),
"keyActualValue": sprintf("'azurerm_managed_disk[%s].encryption_settings' is undefined or null", [name]),
"searchLine": common_lib.build_search_line(["resource", "azurerm_managed_disk", name], []),
"remediation": null,
"remediationType": null
}
} else = results {
resource.encryption_settings == [[],{}][_] # [] for tfplan support
results := {
"searchKey": sprintf("azurerm_managed_disk[%s].encryption_settings", [name]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("'azurerm_managed_disk[%s].encryption_settings' should be defined and not null", [name]),
"keyActualValue": sprintf("'azurerm_managed_disk[%s].encryption_settings' is set to '%v", [name, resource.encryption_settings]),
"searchLine": common_lib.build_search_line(["resource", "azurerm_managed_disk", name, "encryption_settings"], []),
"remediation": null,
"remediationType": null
}
} else = results {
resource.encryption_settings.enabled == false
results := {
"searchKey": sprintf("azurerm_managed_disk[%s].encryption_settings.enabled", [name]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("azurerm_managed_disk[%s].encryption_settings.enabled should be true ", [name]),
"keyActualValue": sprintf("azurerm_managed_disk[%s].encryption_settings.enabled is false", [name]),
"searchLine": common_lib.build_search_line(["resource","azurerm_managed_disk" ,name ,"encryption_settings", "enabled"], []),
"remediation": json.marshal({
"before": "false",
"after": "true"
}),
"remediationType": "replacement",
"keyExpectedValue": sprintf("'azurerm_managed_disk[%s].encryption_settings.enabled' should be set to true", [name]),
"keyActualValue": sprintf("'azurerm_managed_disk[%s].encryption_settings.enabled' is set to false", [name]),
"searchLine": common_lib.build_search_line(["resource", "azurerm_managed_disk", name, "encryption_settings", "enabled"], []),
"remediation": json.marshal({"before": "false", "after": "true"}),
"remediationType": "replacement"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,63 @@ resource "azurerm_managed_disk" "negative1" {
storage_account_type = "Standard_LRS"
create_option = "Empty"
disk_size_gb = "1"

encryption_settings = {
enabled = true

encryption_settings {
enabled = true # legacy
}
}

resource "azurerm_managed_disk" "negative2" {
name = "acctestmd"
location = "West US 2"
resource_group_name = azurerm_resource_group.example.name
storage_account_type = "Standard_LRS"
create_option = "Empty"
disk_size_gb = "1"

encryption_settings {

disk_encryption_key {
secret_url = "sample_url"
source_vault_id = "sample_id"
}

key_encryption_key {
secret_url = "sample_url"
source_vault_id = "sample_id"
}

}
}

resource "azurerm_managed_disk" "negative3" {
name = "acctestmd"
location = "West US 2"
resource_group_name = azurerm_resource_group.example.name
storage_account_type = "Standard_LRS"
create_option = "Empty"
disk_size_gb = "1"

encryption_settings {
disk_encryption_key {
secret_url = "sample_url"
source_vault_id = "sample_id"
}
}
tags = {
environment = "staging"
}

resource "azurerm_managed_disk" "negative4" {
name = "acctestmd"
location = "West US 2"
resource_group_name = azurerm_resource_group.example.name
storage_account_type = "Standard_LRS"
create_option = "Empty"
disk_size_gb = "1"

encryption_settings {
key_encryption_key {
secret_url = "sample_url"
source_vault_id = "sample_id"
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,8 @@ resource "azurerm_managed_disk" "positive1" {
create_option = "Empty"
disk_size_gb = "1"

encryption_settings = {
enabled = false
}

tags = {
environment = "staging"
encryption_settings {
enabled = false # legacy
}
}

Expand All @@ -22,9 +18,28 @@ resource "azurerm_managed_disk" "positive2" {
storage_account_type = "Standard_LRS"
create_option = "Empty"
disk_size_gb = "1"


tags = {
environment = "staging"
}
}
# missing "encryption_settings"
}

resource "azurerm_managed_disk" "positive3" {
name = "acctestmd"
location = "West US 2"
resource_group_name = azurerm_resource_group.example.name
storage_account_type = "Standard_LRS"
create_option = "Empty"
disk_size_gb = "1"

encryption_settings {}
}

resource "azurerm_managed_disk" "positive4" {
name = "acctestmd"
location = "West US 2"
resource_group_name = azurerm_resource_group.example.name
storage_account_type = "Standard_LRS"
create_option = "Empty"
disk_size_gb = "1"

encryption_settings = [] # simulates "tfplan"
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@
{
"queryName": "Encryption On Managed Disk Disabled",
"severity": "MEDIUM",
"line": 18
"line": 14
},
{
"queryName": "Encryption On Managed Disk Disabled",
"severity": "MEDIUM",
"line": 33
},
{
"queryName": "Encryption On Managed Disk Disabled",
"severity": "MEDIUM",
"line": 44
}
]
12 changes: 5 additions & 7 deletions pkg/parser/json/tfplan.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,12 @@ func readPlan(plan *hcl_plan.Plan) model.Document {

// readModule will iterate over all planned_value getting the information required
func (kp *KicsPlan) readModule(module *hcl_plan.StateModule) {
// initialize all the types interfaces
// initialize all the types interfaces and fill in all the types interfaces
for _, resource := range module.Resources {
convNamedRes := make(map[string]KicsPlanNamedResource)
kp.Resource[resource.Type] = convNamedRes
}
// fill in all the types interfaces
for _, resource := range module.Resources {
kp.Resource[resource.Type][resource.Name] = resource.AttributeValues
if _, type_map := kp.Resource[resource.Type]; !type_map {
kp.Resource[resource.Type] = make(map[string]KicsPlanNamedResource)
}
kp.Resource[resource.Type][resource.Address] = resource.AttributeValues
}

for _, childModule := range module.ChildModules {
Expand Down
50 changes: 49 additions & 1 deletion pkg/parser/json/tfplan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func TestJson_parseTFPlan(t *testing.T) {
want: model.Document{
"resource": map[string]interface{}{
"fakewebservices_database": map[string]interface{}{
"prod_db": map[string]interface{}{
"fakewebservices_database.prod_db": map[string]interface{}{
"name": "Production DB",
"size": (float64)(256),
},
Expand All @@ -72,6 +72,54 @@ func TestJson_parseTFPlan(t *testing.T) {
want: model.Document{},
wantErr: true,
},
{
name: "test - parse tfplan with duplicate resource names (different addresses)",
args: args{
doc: model.Document{
"format_version": "0.2",
"terraform_version": "1.0.5",
"planned_values": map[string]interface{}{
"root_module": map[string]interface{}{
"resources": []map[string]interface{}{
{
"address": "fakewebservices_database.prod_db[0]",
"type": "fakewebservices_database",
"name": "prod_db",
"values": map[string]interface{}{
"name": "Production DB A",
"size": 256,
},
},
{
"address": "fakewebservices_database.prod_db[1]",
"type": "fakewebservices_database",
"name": "prod_db",
"values": map[string]interface{}{
"name": "Production DB B",
"size": 512,
},
},
},
},
},
},
},
want: model.Document{
"resource": map[string]interface{}{
"fakewebservices_database": map[string]interface{}{
"fakewebservices_database.prod_db[0]": map[string]interface{}{
"name": "Production DB A",
"size": (float64)(256),
},
"fakewebservices_database.prod_db[1]": map[string]interface{}{
"name": "Production DB B",
"size": (float64)(512),
},
},
},
},
wantErr: false,
},
}

for _, tt := range tests {
Expand Down
Loading