From c283b2d55a03cdf4dc6c807d2878dc2bb45de01e Mon Sep 17 00:00:00 2001 From: cxMiguelSilva <100352574+cxMiguelSilva@users.noreply.github.com> Date: Mon, 23 May 2022 15:37:58 +0100 Subject: [PATCH] feat(query): CNI Plugin Does Not Support Network Policies for Kubernetes (#5370) * + CNI Plugin Does Not Support Network Policies * change description * update --- .../metadata.json | 10 +++++ .../query.rego | 40 +++++++++++++++++++ .../test/negative.json | 26 ++++++++++++ .../test/negative2.yaml | 35 ++++++++++++++++ .../test/positive.json | 26 ++++++++++++ .../test/positive2.yaml | 35 ++++++++++++++++ .../test/positive_expected_result.json | 14 +++++++ pkg/analyzer/analyzer.go | 15 ++++++- 8 files changed, 200 insertions(+), 1 deletion(-) create mode 100644 assets/queries/k8s/cni_plugin_does_not_support_network_policies/metadata.json create mode 100644 assets/queries/k8s/cni_plugin_does_not_support_network_policies/query.rego create mode 100644 assets/queries/k8s/cni_plugin_does_not_support_network_policies/test/negative.json create mode 100644 assets/queries/k8s/cni_plugin_does_not_support_network_policies/test/negative2.yaml create mode 100644 assets/queries/k8s/cni_plugin_does_not_support_network_policies/test/positive.json create mode 100644 assets/queries/k8s/cni_plugin_does_not_support_network_policies/test/positive2.yaml create mode 100644 assets/queries/k8s/cni_plugin_does_not_support_network_policies/test/positive_expected_result.json diff --git a/assets/queries/k8s/cni_plugin_does_not_support_network_policies/metadata.json b/assets/queries/k8s/cni_plugin_does_not_support_network_policies/metadata.json new file mode 100644 index 00000000000..97cf45f060f --- /dev/null +++ b/assets/queries/k8s/cni_plugin_does_not_support_network_policies/metadata.json @@ -0,0 +1,10 @@ +{ + "id": "03aabc8c-35d6-481e-9c85-20139cf72d23", + "queryName": "CNI Plugin Does Not Support Network Policies", + "severity": "MEDIUM", + "category": "Networking and Firewall", + "descriptionText": "Ensure the use of CNI Plugin that support Network Policies. If the CNI Plugin in use does not support Network Policies it may not be possible to effectively restrict traffic in the cluster", + "descriptionUrl": "https://kubernetes.io/docs/concepts/extend-kubernetes/compute-storage-net/network-plugins/", + "platform": "Kubernetes", + "descriptionID": "0e8d122c" +} diff --git a/assets/queries/k8s/cni_plugin_does_not_support_network_policies/query.rego b/assets/queries/k8s/cni_plugin_does_not_support_network_policies/query.rego new file mode 100644 index 00000000000..b7db3236bff --- /dev/null +++ b/assets/queries/k8s/cni_plugin_does_not_support_network_policies/query.rego @@ -0,0 +1,40 @@ +package Cx + +import data.generic.k8s as k8sLib +import data.generic.common as common_lib + +CxPolicy[result] { + document := input.document[i] + + common_lib.valid_key(document, "cniVersion") + plugin := document.plugins[j] + plugin.type == "flannel" + + result := { + "documentId": document.id, + "searchKey": sprintf("plugins", []), + "issueType": "IncorrectValue", + "keyExpectedValue": "Plugins should not contain a plugin that does not support Network Policies", + "keyActualValue": "Plugins contains a plugin that does not support Network Policies", + "searchLine": common_lib.build_search_line(["plugins", j, "type"], []), + } +} + +CxPolicy[result] { + document := input.document[i] + document.kind == "ConfigMap" + + cni:= json.unmarshal(document.data["cni-conf.json"]) + plugin := cni.plugins[j] + plugin.type == "flannel" + + result := { + "documentId": document.id, + "searchKey": sprintf("data.cni-conf.json", []), + "issueType": "IncorrectValue", + "keyExpectedValue": "Plugins should not contain a plugin that does not support Network Policies", + "keyActualValue": "Plugins contains a plugin that does not support Network Policies", + "searchLine": common_lib.build_search_line(["data", "cni-conf.json"], []), + } +} + diff --git a/assets/queries/k8s/cni_plugin_does_not_support_network_policies/test/negative.json b/assets/queries/k8s/cni_plugin_does_not_support_network_policies/test/negative.json new file mode 100644 index 00000000000..74e9d872042 --- /dev/null +++ b/assets/queries/k8s/cni_plugin_does_not_support_network_policies/test/negative.json @@ -0,0 +1,26 @@ +{ + "name": "k8s-pod-network", + "cniVersion": "0.3.0", + "plugins": [ + { + "type": "calico", + "log_level": "info", + "datastore_type": "kubernetes", + "nodename": "127.0.0.1", + "ipam": { + "type": "host-local", + "subnet": "usePodCidr" + }, + "policy": { + "type": "k8s" + }, + "kubernetes": { + "kubeconfig": "/etc/cni/net.d/calico-kubeconfig" + } + }, + { + "type": "portmap", + "capabilities": {"portMappings": true} + } + ] +} diff --git a/assets/queries/k8s/cni_plugin_does_not_support_network_policies/test/negative2.yaml b/assets/queries/k8s/cni_plugin_does_not_support_network_policies/test/negative2.yaml new file mode 100644 index 00000000000..796f773905f --- /dev/null +++ b/assets/queries/k8s/cni_plugin_does_not_support_network_policies/test/negative2.yaml @@ -0,0 +1,35 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + name: kube-flannel-cfg + namespace: kube-system + labels: + tier: node + app: calico +data: + cni-conf.json: | + { + "name": "cbr0", + "plugins": [ + { + "type": "calico", + "delegate": { + "hairpinMode": true, + "isDefaultGateway": true + } + }, + { + "type": "portmap", + "capabilities": { + "portMappings": true + } + } + ] + } + net-conf.json: | + { + "Network": "10.244.0.0/16", + "Backend": { + "Type": "vxlan" + } + } diff --git a/assets/queries/k8s/cni_plugin_does_not_support_network_policies/test/positive.json b/assets/queries/k8s/cni_plugin_does_not_support_network_policies/test/positive.json new file mode 100644 index 00000000000..f5af842cc4e --- /dev/null +++ b/assets/queries/k8s/cni_plugin_does_not_support_network_policies/test/positive.json @@ -0,0 +1,26 @@ +{ + "name": "k8s-pod-network", + "cniVersion": "0.3.0", + "plugins": [ + { + "type": "flannel", + "log_level": "info", + "datastore_type": "kubernetes", + "nodename": "127.0.0.1", + "ipam": { + "type": "host-local", + "subnet": "usePodCidr" + }, + "policy": { + "type": "k8s" + }, + "kubernetes": { + "kubeconfig": "/etc/cni/net.d/flannel-kubeconfig" + } + }, + { + "type": "portmap", + "capabilities": {"portMappings": true} + } + ] +} diff --git a/assets/queries/k8s/cni_plugin_does_not_support_network_policies/test/positive2.yaml b/assets/queries/k8s/cni_plugin_does_not_support_network_policies/test/positive2.yaml new file mode 100644 index 00000000000..7d0a402bb57 --- /dev/null +++ b/assets/queries/k8s/cni_plugin_does_not_support_network_policies/test/positive2.yaml @@ -0,0 +1,35 @@ +kind: ConfigMap +apiVersion: v1 +metadata: + name: kube-flannel-cfg + namespace: kube-system + labels: + tier: node + app: flannel +data: + cni-conf.json: | + { + "name": "cbr0", + "plugins": [ + { + "type": "flannel", + "delegate": { + "hairpinMode": true, + "isDefaultGateway": true + } + }, + { + "type": "portmap", + "capabilities": { + "portMappings": true + } + } + ] + } + net-conf.json: | + { + "Network": "10.244.0.0/16", + "Backend": { + "Type": "vxlan" + } + } diff --git a/assets/queries/k8s/cni_plugin_does_not_support_network_policies/test/positive_expected_result.json b/assets/queries/k8s/cni_plugin_does_not_support_network_policies/test/positive_expected_result.json new file mode 100644 index 00000000000..954e413166f --- /dev/null +++ b/assets/queries/k8s/cni_plugin_does_not_support_network_policies/test/positive_expected_result.json @@ -0,0 +1,14 @@ +[ + { + "queryName": "CNI Plugin Does Not Support Network Policies", + "severity": "MEDIUM", + "line": 6, + "fileName": "positive.json" + }, + { + "queryName": "CNI Plugin Does Not Support Network Policies", + "severity": "MEDIUM", + "line": 10, + "fileName": "positive2.yaml" + } +] diff --git a/pkg/analyzer/analyzer.go b/pkg/analyzer/analyzer.go index 2dc6856a906..461b6319bb4 100644 --- a/pkg/analyzer/analyzer.go +++ b/pkg/analyzer/analyzer.go @@ -55,6 +55,9 @@ var ( buildahRegex = regexp.MustCompile(`\s*buildah\s*from\s*\w+`) dockerComposeVersionRegex = regexp.MustCompile(`\s*version\s*:`) dockerComposeServicesRegex = regexp.MustCompile(`\s*services\s*:`) + cniK8sNameRegex = regexp.MustCompile("\\s*\"?name\"?\\s*:") + cniK8sVersionRegex = regexp.MustCompile("\\s*\"?cniVersion\"?\\s*:") + cniK8sPluginsRegex = regexp.MustCompile("\\s*\"?plugins\"?\\s*:") ) var ( @@ -76,7 +79,7 @@ var ( "buildah": {"buildah"}, "cloudformation": {"cloudformation"}, "dockercompose": {"dockercompose"}, - "kubernetes": {"kubernetes"}, + "kubernetes": {"kubernetes", "cniK8s"}, "openapi": {"openapi"}, "terraform": {"terraform", "cdkTf"}, } @@ -188,6 +191,13 @@ var types = map[string]regexSlice{ dockerComposeServicesRegex, }, }, + "cniK8s": { + regex: []*regexp.Regexp{ + cniK8sNameRegex, + cniK8sVersionRegex, + cniK8sPluginsRegex, + }, + }, } // Analyze will go through the slice paths given and determine what type of queries should be loaded @@ -362,6 +372,9 @@ func checkReturnType(path, returnType, ext string, content []byte) string { if returnType == "cdkTf" { return terraform } + if returnType == "cniK8s" { + return kubernetes + } if utils.Contains(returnType, armRegexTypes) { return arm }