Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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