Skip to content

Commit

Permalink
feat(query): added "RDP Access Is Not Restricted" for Google Deployme…
Browse files Browse the repository at this point in the history
…nt Manager (Checkmarx#4730)

Signed-off-by: JoaoDanielRufino <[email protected]>
  • Loading branch information
JoaoDanielRufino authored Feb 1, 2022
1 parent 4556e8e commit 96a8762
Show file tree
Hide file tree
Showing 13 changed files with 175 additions and 67 deletions.
2 changes: 1 addition & 1 deletion assets/libraries/common.rego
Original file line number Diff line number Diff line change
Expand Up @@ -437,4 +437,4 @@ is_recommended_tls(field) {
is_unrestricted(sourceRange) {
cidrs := {"0.0.0.0/0", "::/0"}
sourceRange == cidrs[_]
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package Cx

import data.generic.ansible as ansLib
import data.generic.common as common_lib

CxPolicy[result] {
task := ansLib.tasks[id][t]
modules := {"google.cloud.gcp_compute_firewall", "gcp_compute_firewall"}
instance := task[modules[m]]
ansLib.checkState(instance)

isDirIngress(instance)
common_lib.is_ingress(instance)
common_lib.is_unrestricted(instance.source_ranges[_])

allowed := instance.allowed
ansLib.allowsPort(allowed[k], "3389")
Expand All @@ -21,11 +23,3 @@ CxPolicy[result] {
"keyActualValue": sprintf("gcp_compute_firewall.allowed.ip_protocol=%s.ports contain RDP port (3389) with unrestricted ingress traffic", [allowed[k].ip_protocol]),
}
}

isDirIngress(instance) {
instance.direction == "INGRESS"
} else {
not instance.direction
} else = false {
true
}
Original file line number Diff line number Diff line change
@@ -1,36 +1,40 @@
- name: rdp_in_range
google.cloud.gcp_compute_firewall:
name: test_object
source_ranges:
- "0.0.0.0/0"
allowed:
- ip_protocol: tcp
ports:
- '22'
- '80'
- '8080'
- '2000-4000'
- ip_protocol: tcp
ports:
- "22"
- "80"
- "8080"
- "2000-4000"
target_tags:
- test-ssh-server
- staging-ssh-server
- test-ssh-server
- staging-ssh-server
source_tags:
- test-ssh-clients
- test-ssh-clients
project: test_project
auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
state: present
- name: rdp_in_port
google.cloud.gcp_compute_firewall:
name: test_object
source_ranges:
- "0.0.0.0/0"
allowed:
- ip_protocol: tcp
ports:
- '22'
- '80'
- '3389'
- ip_protocol: tcp
ports:
- "22"
- "80"
- "3389"
target_tags:
- test-ssh-server
- staging-ssh-server
- test-ssh-server
- staging-ssh-server
source_tags:
- test-ssh-clients
- test-ssh-clients
project: test_project
auth_kind: serviceaccount
service_account_file: "/tmp/auth.pem"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[
{
"queryName": "RDP Access Is Not Restricted",
"severity": "MEDIUM",
"line": 6
},
{
"queryName": "RDP Access Is Not Restricted",
"severity": "MEDIUM",
"line": 25
}
{
"queryName": "RDP Access Is Not Restricted",
"severity": "MEDIUM",
"line": 8
},
{
"queryName": "RDP Access Is Not Restricted",
"severity": "MEDIUM",
"line": 29
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"id": "50cb6c3b-c878-4b88-b50e-d1421bada9e8",
"queryName": "RDP Access Is Not Restricted",
"severity": "MEDIUM",
"category": "Networking and Firewall",
"descriptionText": "Check if the Google compute firewall allows unrestricted RDP access. Allowed ports should not contain RDP port 3389",
"descriptionUrl": "https://cloud.google.com/compute/docs/reference/rest/v1/firewalls",
"platform": "GoogleDeploymentManager",
"descriptionID": "cae2eeea",
"cloudProvider": "gcp"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package Cx

import data.generic.common as common_lib

CxPolicy[result] {
resource := input.document[i].resources[idx]
resource.type == "compute.v1.firewall"
properties := resource.properties

common_lib.is_ingress(properties)
common_lib.is_unrestricted(properties.sourceRanges[_])
isRDPport(properties.allowed[a])

result := {
"documentId": input.document[i].id,
"searchKey": sprintf("resources.name={{%s}}.properties.allowed", [resource.name]),
"issueType": "IncorrectValue",
"keyExpectedValue": "'allowed.ports' to not include RDP port 3389",
"keyActualValue": "'allowed.ports' includes RDP port 3389",
"searchLine": common_lib.build_search_line(["resources", idx, "properties", "allowed", a], []),
}
}

isRDPport(allow) {
isTCPorUDP(allow.IPProtocol)
contains(allow.ports[j], "-")
port_bounds := split(allow.ports[j], "-")
low_bound := to_number(port_bounds[0])
high_bound := to_number(port_bounds[1])
isInBounds(low_bound, high_bound)
} else {
isTCPorUDP(allow.IPProtocol)
contains(allow.ports[j], "-") == false
to_number(allow.ports[j]) == 3389
}

isInBounds(low, high) {
low <= 3389
high >= 3389
}

isTCPorUDP(protocol) {
protocols := {"tcp", "udp"}
lower(protocol) == protocols[_]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
resources:
- name: firewall
type: compute.v1.firewall
properties:
name: my-firewall
allowed:
- IPProtocol: icmp
ports:
- "80"
- "8080"
- "1000-2000"
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
resources:
- name: firewall
type: compute.v1.firewall
properties:
name: my-firewall
sourceRanges:
- "0.0.0.0/0"
allowed:
- IPProtocol: icmp
ports:
- "80"
- "8080"
- "1000-2000"
- IPProtocol: tcp
ports:
- "80"
- "8080"
- "1000-2000"
- "3389"
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
resources:
- name: firewall
type: compute.v1.firewall
properties:
name: my-firewall
sourceRanges:
- "::/0"
allowed:
- IPProtocol: icmp
ports:
- "80"
- "8080"
- "1000-2000"
- IPProtocol: udp
ports:
- "80"
- "8080"
- "1000-2000"
- "21-3389"
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{
"queryName": "RDP Access Is Not Restricted",
"severity": "MEDIUM",
"line": 14,
"filename": "positive1.yaml"
},
{
"queryName": "RDP Access Is Not Restricted",
"severity": "MEDIUM",
"line": 14,
"filename": "positive2.yaml"
}
]
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
package Cx

import data.generic.common as common_lib

CxPolicy[result] {
firewall := input.document[i].resource.google_compute_firewall[name]

isDirIngress(firewall)
common_lib.is_ingress(firewall)
common_lib.is_unrestricted(firewall.source_ranges[_])
allowed := getAllowed(firewall)
isRDPport(allowed[_])
isRDPport(allowed[a])

result := {
"documentId": input.document[i].id,
"searchKey": sprintf("google_compute_firewall[%s].allow.ports", [name]),
"issueType": "IncorrectValue",
"keyExpectedValue": sprintf("'google_compute_firewall[%s].allow.ports' does not include RDP port 3389", [name]),
"keyActualValue": sprintf("'google_compute_firewall[%s].allow.ports' includes RDP port 3389", [name]),
"searchLine": common_lib.build_search_line(["google_compute_firewall", name, "allow", a], []),
}
}

Expand All @@ -26,27 +30,15 @@ getAllowed(firewall) = allowed {
allowed := [firewall.allow]
}

isDirIngress(firewall) {
firewall.direction == "INGRESS"
}

isDirIngress(firewall) {
not firewall.direction
}

isRDPport(allow) {
isTCPorUDP(allow.protocol)
some j
contains(allow.ports[j], "-")
port_bounds := split(allow.ports[j], "-")
low_bound := to_number(port_bounds[0])
high_bound := to_number(port_bounds[1])
isInBounds(low_bound, high_bound)
}

isRDPport(allow) {
} else {
isTCPorUDP(allow.protocol)
some j
contains(allow.ports[j], "-") == false
to_number(allow.ports[j]) == 3389
}
Expand All @@ -57,9 +49,6 @@ isInBounds(low, high) {
}

isTCPorUDP(protocol) {
lower(protocol) == "tcp"
}

isTCPorUDP(protocol) {
lower(protocol) == "udp"
protocols := {"tcp", "udp"}
lower(protocol) == protocols[_]
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ resource "google_compute_firewall" "positive1" {
}

source_tags = ["web"]
source_ranges = ["0.0.0.0/0"]
}

resource "google_compute_firewall" "positive2" {
Expand All @@ -25,4 +26,5 @@ resource "google_compute_firewall" "positive2" {
}

source_tags = ["web"]
source_ranges = ["::/0"]
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
[
{
"queryName": "RDP Access Is Not Restricted",
"severity": "MEDIUM",
"line": 12
},
{
"queryName": "RDP Access Is Not Restricted",
"severity": "MEDIUM",
"line": 24
}
{
"queryName": "RDP Access Is Not Restricted",
"severity": "MEDIUM",
"line": 12
},
{
"queryName": "RDP Access Is Not Restricted",
"severity": "MEDIUM",
"line": 25
}
]

0 comments on commit 96a8762

Please sign in to comment.