Skip to content
Draft
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
@@ -1,25 +1,108 @@
package Cx

import future.keywords.if
import data.generic.common as common_lib

CxPolicy[result] {
vm := input.document[i].playbooks[k].azure_rm_virtualmachine
is_linux_vm(vm)
not vm.ssh_password_enabled == false
not vm.linux_config.disable_password_authentication == false
is_linux_vm(vm)
res := get_results(vm, ["playbooks", k, "azure_rm_virtualmachine"])
result := {
"documentId": input.document[i].id,
"resourceType": "azure_rm_virtualmachine",
"resourceName": vm.name,
"searchKey": sprintf("azure_rm_virtualmachine[%s].ssh_public_keys", [vm.name]),
"searchKey": res.searchKey,
"issueType": res.issueType,
"keyExpectedValue": res.keyExpectedValue,
"keyActualValue": res.keyActualValue,
"searchLine": res.searchLine,
}
}

CxPolicy[result] {
vm := input.document[i].playbooks[k].tasks[y].azure_rm_virtualmachine
is_linux_vm(vm)
res := get_results(vm, ["playbooks", k, "tasks", y, "azure_rm_virtualmachine"])
result := {
"documentId": input.document[i].id,
"resourceType": "azure_rm_virtualmachine",
"resourceName": vm.name,
"searchKey": res.searchKey,
"issueType": res.issueType,
"keyExpectedValue": res.keyExpectedValue,
"keyActualValue": res.keyActualValue,
"searchLine": res.searchLine,
}
}

get_results(vm, path) = res { # both "ssh_password_enabled" and "linux_config" undefined
not common_lib.valid_key(vm, "ssh_password_enabled")
not common_lib.valid_key(vm, "linux_config")
res := {
"searchKey": sprintf("azure_rm_virtualmachine.%s", [vm.name]),
"issueType": "MissingAttribute",
"keyExpectedValue": sprintf("'azure_rm_virtualmachine[%s]' should be using SSH keys for authentication", [vm.name]),
"keyActualValue": sprintf("'azure_rm_virtualmachine[%s]' is using username and password for authentication", [vm.name]),
"keyExpectedValue": sprintf("'azure_rm_virtualmachine[%s]' should set 'ssh_password_enabled' to false and 'linux_config.disable_password_authentication' to true", [vm.name]),
"keyActualValue": sprintf("'azure_rm_virtualmachine[%s].ssh_password_enabled' and 'linux_config' are both undefined", [vm.name]),
"searchLine": common_lib.build_search_line(path, []),
}
} else = res { # "ssh_password_enabled" undefined with "linux_config" missing "disable_password_authentication" field
not common_lib.valid_key(vm, "ssh_password_enabled")
common_lib.valid_key(vm, "linux_config")
not common_lib.valid_key(vm.linux_config, "disable_password_authentication")
res := {
"searchKey": sprintf("azure_rm_virtualmachine.%s.linux_config", [vm.name]),
"issueType": "MissingAttribute",
"keyExpectedValue": sprintf("'azure_rm_virtualmachine[%s]' should set 'ssh_password_enabled' to false and 'linux_config.disable_password_authentication' to true", [vm.name]),
"keyActualValue": sprintf("'azure_rm_virtualmachine[%s].ssh_password_enabled' and 'linux_config.disable_password_authentication' are both undefined", [vm.name]),
"searchLine": common_lib.build_search_line(path, ["linux_config"]),
}
} else = res { # "ssh_password_enabled" undefined with "linux_config.disable_password_authentication" set to false
not common_lib.valid_key(vm, "ssh_password_enabled")
common_lib.valid_key(vm, "linux_config")
vm.linux_config.disable_password_authentication == false
res := {
"searchKey": sprintf("azure_rm_virtualmachine.%s.linux_config.disable_password_authentication", [vm.name]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("'azure_rm_virtualmachine[%s]' should set 'ssh_password_enabled' to false and 'linux_config.disable_password_authentication' to true", [vm.name]),
"keyActualValue": sprintf("'azure_rm_virtualmachine[%s].ssh_password_enabled' is undefined and 'linux_config.disable_password_authentication' is set to false", [vm.name]),
"searchLine": common_lib.build_search_line(path, ["linux_config", "disable_password_authentication"]),
}
} else = res { # "ssh_password_enabled" set to true, "linux_config" undefined
vm.ssh_password_enabled == true
not common_lib.valid_key(vm, "linux_config")
res := {
"searchKey": sprintf("azure_rm_virtualmachine.%s.ssh_password_enabled", [vm.name]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("'azure_rm_virtualmachine[%s]' should set 'ssh_password_enabled' to false and 'linux_config.disable_password_authentication' to true", [vm.name]),
"keyActualValue": sprintf("'azure_rm_virtualmachine[%s].ssh_password_enabled' is set to true and 'linux_config' is undefined", [vm.name]),
"searchLine": common_lib.build_search_line(path, ["ssh_password_enabled"]),
}
} else = res { # "ssh_password_enabled" set to true with "linux_config" missing "disable_password_authentication" field
vm.ssh_password_enabled == true
common_lib.valid_key(vm, "linux_config")
not common_lib.valid_key(vm.linux_config, "disable_password_authentication")
res := {
"searchKey": sprintf("azure_rm_virtualmachine.%s.ssh_password_enabled", [vm.name]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("'azure_rm_virtualmachine[%s]' should set 'ssh_password_enabled' to false and 'linux_config.disable_password_authentication' to true", [vm.name]),
"keyActualValue": sprintf("'azure_rm_virtualmachine[%s].ssh_password_enabled' is true and 'linux_config.disable_password_authentication' is undefined", [vm.name]),
"searchLine": common_lib.build_search_line(path, ["ssh_password_enabled"]),
}
} else = res { # "ssh_password_enabled" set to true with "linux_config.disable_password_authentication" set to false
vm.ssh_password_enabled == true
common_lib.valid_key(vm, "linux_config")
vm.linux_config.disable_password_authentication == false
res := {
"searchKey": sprintf("azure_rm_virtualmachine.%s.ssh_password_enabled", [vm.name]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("'azure_rm_virtualmachine[%s]' should set 'ssh_password_enabled' to false and 'linux_config.disable_password_authentication' to true", [vm.name]),
"keyActualValue": sprintf("'azure_rm_virtualmachine[%s].ssh_password_enabled' is set to true and 'linux_config.disable_password_authentication' to false", [vm.name]),
"searchLine": common_lib.build_search_line(path, ["ssh_password_enabled"]),
}
}

is_linux_vm(vm) {
lower(vm.os_type) == "linux"
lower(vm.os_type) == "linux"
} else {
not vm.os_type
}
not common_lib.valid_key(vm, "os_type")
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
- name: Create a VM with a custom image
- name: ssh_password_enabled false, no linux_config
azure_rm_virtualmachine:
resource_group: myResourceGroup
name: testvm001
name: negative1
vm_size: Standard_DS1_v2
ssh_password_enabled: false
ssh_public_keys:
- path: ~/.ssh/id_rsa.pub
key_data: somegeneratedkeydata
image: customimage001
os_type: Linux
os_type: Linux
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
- hosts: localhost
tasks:
- name: ssh_password_enabled false and disable_password_authentication true
azure_rm_virtualmachine:
resource_group: myResourceGroup
name: negative2_1
vm_size: Standard_DS1_v2
admin_username: adminUser
os_type: Linux
ssh_password_enabled: false
linux_config:
disable_password_authentication: true

- name: both ssh_password_enabled false and disable_password_authentication false - ssh_password_enabled will still prevent basic authentication
azure_rm_virtualmachine:
resource_group: myResourceGroup
name: negative2_2
vm_size: Standard_DS1_v2
admin_username: adminUser
os_type: Linux
ssh_password_enabled: false
linux_config:
disable_password_authentication: false

- name: no ssh_password_enabled, linux_config.disable_password_authentication explicitly true
azure_rm_virtualmachine:
resource_group: myResourceGroup
name: negative2_3
vm_size: Standard_DS1_v2
admin_username: adminUser
os_type: Linux
linux_config:
disable_password_authentication: true

- name: Windows VM is not checked
azure_rm_virtualmachine:
resource_group: myResourceGroup
name: negative2_4
vm_size: Standard_DS1_v2
admin_username: adminUser
admin_password: Password123!
os_type: Windows
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
- name: Create a VM with a custom image
- name: neither ssh_password_enabled nor linux_config defined
azure_rm_virtualmachine:
resource_group: myResourceGroup
name: testvm001
name: positive1
vm_size: Standard_DS1_v2
admin_username: adminUser
admin_password: password01
image: customimage001
os_type: Linux
os_type: Linux
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
--- # support for multiple azure_rm_virtualmachines (tasks set)
- hosts: localhost
tasks:
- name: no ssh_password_enabled, linux_config defined but disable_password_authentication undefined
azure_rm_virtualmachine:
resource_group: myResourceGroup
name: positive2_1
vm_size: Standard_DS1_v2
admin_username: adminUser
admin_password: Password123!
os_type: Linux
linux_config: {}

- name: no ssh_password_enabled, disable_password_authentication set to false
azure_rm_virtualmachine:
resource_group: myResourceGroup
name: positive2_2
vm_size: Standard_DS1_v2
admin_username: adminUser
admin_password: Password123!
os_type: Linux
linux_config:
disable_password_authentication: false

- name: ssh_password_enabled true, no linux_config
azure_rm_virtualmachine:
resource_group: myResourceGroup
name: positive2_3
vm_size: Standard_DS1_v2
admin_username: adminUser
admin_password: Password123!
os_type: Linux
ssh_password_enabled: true

- name: ssh_password_enabled true, linux_config defined but disable_password_authentication undefined
azure_rm_virtualmachine:
resource_group: myResourceGroup
name: positive2_4
vm_size: Standard_DS1_v2
admin_username: adminUser
admin_password: Password123!
os_type: Linux
ssh_password_enabled: true
linux_config: {}

- name: ssh_password_enabled set to true and disable_password_authentication set to false
azure_rm_virtualmachine:
resource_group: myResourceGroup
name: positive2_5
vm_size: Standard_DS1_v2
admin_username: adminUser
admin_password: Password123!
os_type: Linux
ssh_password_enabled: true
linux_config:
disable_password_authentication: false
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,37 @@
{
"queryName": "Azure Instance Using Basic Authentication",
"severity": "MEDIUM",
"line": 1,
"fileName": "positive.yaml"
"line": 3,
"fileName": "positive1.yaml"
},
{
"queryName": "Azure Instance Using Basic Authentication",
"severity": "MEDIUM",
"line": 12,
"fileName": "positive2.yaml"
},
{
"queryName": "Azure Instance Using Basic Authentication",
"severity": "MEDIUM",
"line": 23,
"fileName": "positive2.yaml"
},
{
"queryName": "Azure Instance Using Basic Authentication",
"severity": "MEDIUM",
"line": 33,
"fileName": "positive2.yaml"
},
{
"queryName": "Azure Instance Using Basic Authentication",
"severity": "MEDIUM",
"line": 43,
"fileName": "positive2.yaml"
},
{
"queryName": "Azure Instance Using Basic Authentication",
"severity": "MEDIUM",
"line": 54,
"fileName": "positive2.yaml"
}
]
17 changes: 7 additions & 10 deletions assets/queries/cicd/github/run_block_injection/query.rego
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ CxPolicy[result] {

result := {
"documentId": input.document[i].id,
"searchKey": sprintf("run={{%s}}", [run]),
"searchKey": sprintf("jobs.%s.steps.run", [j]),
"issueType": "IncorrectValue",
"keyExpectedValue": "Run block does not contain dangerous input controlled by user.",
"keyActualValue": "Run block contains dangerous input controlled by user.",
Expand All @@ -45,7 +45,7 @@ CxPolicy[result] {

result := {
"documentId": input.document[i].id,
"searchKey": sprintf("run={{%s}}", [run]),
"searchKey": sprintf("jobs.%s.steps.run", [j]),
"issueType": "IncorrectValue",
"keyExpectedValue": "Run block does not contain dangerous input controlled by user.",
"keyActualValue": "Run block contains dangerous input controlled by user.",
Expand All @@ -69,7 +69,7 @@ CxPolicy[result] {

result := {
"documentId": input.document[i].id,
"searchKey": sprintf("run={{%s}}", [run]),
"searchKey": sprintf("jobs.%s.steps.run", [j]),
"issueType": "IncorrectValue",
"keyExpectedValue": "Run block does not contain dangerous input controlled by user.",
"keyActualValue": "Run block contains dangerous input controlled by user.",
Expand All @@ -92,7 +92,7 @@ CxPolicy[result] {

result := {
"documentId": input.document[i].id,
"searchKey": sprintf("run={{%s}}", [run]),
"searchKey": sprintf("jobs.%s.steps.run", [j]),
"issueType": "IncorrectValue",
"keyExpectedValue": "Run block does not contain dangerous input controlled by user.",
"keyActualValue": "Run block contains dangerous input controlled by user.",
Expand All @@ -116,7 +116,7 @@ CxPolicy[result] {

result := {
"documentId": input.document[i].id,
"searchKey": sprintf("run={{%s}}", [run]),
"searchKey": sprintf("jobs.%s.steps.run", [j]),
"issueType": "IncorrectValue",
"keyExpectedValue": "Run block does not contain dangerous input controlled by user.",
"keyActualValue": "Run block contains dangerous input controlled by user.",
Expand All @@ -143,7 +143,7 @@ CxPolicy[result] {

result := {
"documentId": input.document[i].id,
"searchKey": sprintf("run={{%s}}", [run]),
"searchKey": sprintf("jobs.%s.steps.run", [j]),
"issueType": "IncorrectValue",
"keyExpectedValue": "Run block does not contain dangerous input controlled by user.",
"keyActualValue": "Run block contains dangerous input controlled by user.",
Expand All @@ -166,7 +166,7 @@ CxPolicy[result] {

result := {
"documentId": input.document[i].id,
"searchKey": sprintf("run={{%s}}", [run]),
"searchKey": sprintf("jobs.%s.steps.run", [j]),
"issueType": "IncorrectValue",
"keyExpectedValue": "Run block does not contain dangerous input controlled by user.",
"keyActualValue": "Run block contains dangerous input controlled by user.",
Expand All @@ -175,12 +175,9 @@ CxPolicy[result] {
}
}



containsPatterns(str, patterns) = matched {
matched := {pattern |
pattern := patterns[_]
regex.match(pattern, str)
}
}

Loading
Loading