Repository: zegl/kube-score
Pull request #8 (2018-09-26 18:04:47)

fea(securityContext) add checks for the containers securityContext


Patch:
diff --git a/score/container.go b/score/container.go
index 20daf6c..48e3c6c 100644
--- a/score/container.go
+++ b/score/container.go
@@ -181,5 +181,54 @@ func scoreContainerProbes(podTemplate corev1.PodTemplateSpec) (score scorecard.T
 		score.Grade = 0
 	}
 
+	return
+}
+
+func scoreContainerSecurityContext(podTemplate corev1.PodTemplateSpec) (score scorecard.TestScore) {
+	score.Name = "Container Security Context"
+
+	allContainers := podTemplate.Spec.InitContainers
+	allContainers = append(allContainers, podTemplate.Spec.Containers...)
+
+	hasPrivileged := false
+	hasWritableRootFS := false
+	hasLowUserID := false
+	hasLowGroupID := false
+
+	for _, container := range allContainers {
+
+		if container.SecurityContext == nil {
+			continue
+		}
+
+		sec := container.SecurityContext
+
+		if sec.Privileged != nil && *sec.Privileged {
+			hasPrivileged = true
+			score.Comments = append(score.Comments, "The pod has a privileged container")
+		}
+
+		if sec.ReadOnlyRootFilesystem != nil && *sec.ReadOnlyRootFilesystem == false {
+			hasWritableRootFS = true
+			score.Comments = append(score.Comments, "The pod has a container with a writable root filesystem")
+		}
+
+		if sec.RunAsUser != nil && *sec.RunAsUser < 10000 {
+			hasLowUserID = true
+			score.Comments = append(score.Comments, "The pod has a container running with a low user ID")
+		}
+
+		if sec.RunAsGroup != nil && *sec.RunAsGroup < 10000 {
+			hasLowGroupID = true
+			score.Comments = append(score.Comments, "The pod has a container running with a low group ID")
+		}
+	}
+
+	if hasPrivileged || hasWritableRootFS || hasLowUserID || hasLowGroupID {
+		score.Grade = 0
+	} else {
+		score.Grade = 10
+	}
+
 	return
 }
\ No newline at end of file
diff --git a/score/score.go b/score/score.go
index adfc7ba..67b6367 100644
--- a/score/score.go
+++ b/score/score.go
@@ -189,6 +189,7 @@ func Score(files []io.Reader) (*scorecard.Scorecard, error) {
 		scoreContainerImagePullPolicy,
 		scorePodHasNetworkPolicy(networkPolies),
 		scoreContainerProbes,
+		scoreContainerSecurityContext,
 	}
 
 	scoreCard := scorecard.New()


Test patch:
diff --git a/score/score_test.go b/score/score_test.go
index 491f557..a8974b6 100644
--- a/score/score_test.go
+++ b/score/score_test.go
@@ -145,4 +145,24 @@ func TestCronJobBatchv1beta1(t *testing.T) {
 
 func TestJobBatchv1(t *testing.T) {
 	testExpectedScore(t, "job-batchv1.yaml", "Unstable version", 10)
+}
+
+func TestContainerSecurityContextPrivilegied(t *testing.T) {
+	testExpectedScore(t, "pod-security-context-privilegied.yaml", "Container Security Context", 0)
+}
+
+func TestContainerSecurityContextNonPrivilegied(t *testing.T) {
+	testExpectedScore(t, "pod-security-context-non-privilegied.yaml", "Container Security Context", 10)
+}
+
+func TestContainerSecurityContextLowUser(t *testing.T) {
+	testExpectedScore(t, "pod-security-context-low-user-id.yaml", "Container Security Context", 0)
+}
+
+func TestContainerSecurityContextLowGroup(t *testing.T) {
+	testExpectedScore(t, "pod-security-context-low-group-id.yaml", "Container Security Context", 0)
+}
+
+func TestContainerSecurityContextHighIds(t *testing.T) {
+	testExpectedScore(t, "pod-security-context-high-ids.yaml", "Container Security Context", 10)
 }
\ No newline at end of file
diff --git a/score/testdata/pod-security-context-high-ids.yaml b/score/testdata/pod-security-context-high-ids.yaml
new file mode 100644
index 0000000..829d658
--- /dev/null
+++ b/score/testdata/pod-security-context-high-ids.yaml
@@ -0,0 +1,11 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: pod-test-1
+spec:
+  containers:
+  - name: foobar
+    image: foo/bar:latest
+    securityContext:
+      runAsUser: 12000
+      runAsGroup: 13000
\ No newline at end of file
diff --git a/score/testdata/pod-security-context-low-group-id.yaml b/score/testdata/pod-security-context-low-group-id.yaml
new file mode 100644
index 0000000..d0c1f05
--- /dev/null
+++ b/score/testdata/pod-security-context-low-group-id.yaml
@@ -0,0 +1,11 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: pod-test-1
+spec:
+  containers:
+  - name: foobar
+    image: foo/bar:latest
+    securityContext:
+      runAsUser: 15000
+      runAsGroup: 0
\ No newline at end of file
diff --git a/score/testdata/pod-security-context-low-user-id.yaml b/score/testdata/pod-security-context-low-user-id.yaml
new file mode 100644
index 0000000..fa57a41
--- /dev/null
+++ b/score/testdata/pod-security-context-low-user-id.yaml
@@ -0,0 +1,11 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: pod-test-1
+spec:
+  containers:
+  - name: foobar
+    image: foo/bar:latest
+    securityContext:
+      runAsUser: 0
+      runAsGroup: 20000
\ No newline at end of file
diff --git a/score/testdata/pod-security-context-non-privilegied.yaml b/score/testdata/pod-security-context-non-privilegied.yaml
new file mode 100644
index 0000000..2eb1dbe
--- /dev/null
+++ b/score/testdata/pod-security-context-non-privilegied.yaml
@@ -0,0 +1,10 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: pod-test-1
+spec:
+  containers:
+  - name: foobar
+    image: foo/bar:latest
+    securityContext:
+      privileged: False
\ No newline at end of file
diff --git a/score/testdata/pod-security-context-privilegied.yaml b/score/testdata/pod-security-context-privilegied.yaml
new file mode 100644
index 0000000..86d070f
--- /dev/null
+++ b/score/testdata/pod-security-context-privilegied.yaml
@@ -0,0 +1,10 @@
+apiVersion: v1
+kind: Pod
+metadata:
+  name: pod-test-1
+spec:
+  containers:
+  - name: foobar
+    image: foo/bar:latest
+    securityContext:
+      privileged: True
\ No newline at end of file