Skip to content

Commit

Permalink
pass RunAsNonRoot if RunAsUser > 0
Browse files Browse the repository at this point in the history
  • Loading branch information
rbren committed Nov 11, 2019
1 parent 7e35b03 commit 5b7b039
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 11 deletions.
19 changes: 8 additions & 11 deletions pkg/validator/container.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,19 +235,16 @@ func (cv *ContainerValidation) validateSecurity(conf *config.Configuration, cont
name := "RunAsRootAllowed"
if conf.IsActionable(conf.Security, name, controllerName) {
id := config.GetIDFromField(conf.Security, name)
if getBoolValue(securityContext.RunAsNonRoot) {
runAsRootSuccess := false
if getBoolValue(securityContext.RunAsNonRoot) || (securityContext.RunAsUser != nil && *securityContext.RunAsUser > 0) {
// Check if the container is explicitly set to True (pass)
runAsRootSuccess = true
} else if securityContext.RunAsNonRoot == nil && securityContext.RunAsUser == nil {
// Or if the container values are unset, check the pod values
runAsRootSuccess = getBoolValue(podSecurityContext.RunAsNonRoot) || (podSecurityContext.RunAsUser != nil && *podSecurityContext.RunAsUser > 0)
}
if runAsRootSuccess {
cv.addSuccess(messages.RunAsRootSuccess, category, id)
} else if securityContext.RunAsNonRoot == nil {
// Check if the value in the container spec if nil (thus defaulting to the podspec)
// Check if the container value is not set
if getBoolValue(podSecurityContext.RunAsNonRoot) {
// if the pod spec default for containers is true, then pass
cv.addSuccess(messages.RunAsRootSuccess, category, id)
} else {
// else fail as RunAsNonRoot defaults to false
cv.addFailure(messages.RunAsRootFailure, conf.Security.RunAsRootAllowed, category, id)
}
} else {
cv.addFailure(messages.RunAsRootFailure, conf.Security.RunAsRootAllowed, category, id)
}
Expand Down
130 changes: 130 additions & 0 deletions pkg/validator/container_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
package validator

import (
"fmt"
"testing"

conf "github.com/fairwindsops/polaris/pkg/config"
Expand Down Expand Up @@ -1075,6 +1076,135 @@ func TestValidateSecurity(t *testing.T) {
}
}

func TestValidateRunAsRoot(t *testing.T) {
falseVar := false
trueVar := true
nonRootUser := int64(1000)
rootUser := int64(0)
config := conf.Configuration{
Security: conf.Security{
RunAsRootAllowed: conf.SeverityWarning,
},
}
testCases := []struct {
cv ContainerValidation
message ResultMessage
}{
{
cv: ContainerValidation{
ResourceValidation: &ResourceValidation{},
Container: &corev1.Container{Name: "", SecurityContext: &corev1.SecurityContext{
RunAsNonRoot: nil,
}},
parentPodSpec: corev1.PodSpec{
SecurityContext: &corev1.PodSecurityContext{
RunAsNonRoot: &falseVar,
},
},
},
message: ResultMessage{
ID: "runAsRootAllowed",
Message: "Should not be allowed to run as root",
Type: "warning",
Category: "Security",
},
},
{
cv: ContainerValidation{
ResourceValidation: &ResourceValidation{},
Container: &corev1.Container{Name: "", SecurityContext: &corev1.SecurityContext{
RunAsNonRoot: &trueVar,
}},
parentPodSpec: corev1.PodSpec{
SecurityContext: &corev1.PodSecurityContext{
RunAsNonRoot: &falseVar,
},
},
},
message: ResultMessage{
ID: "runAsRootAllowed",
Message: "Is not allowed to run as root",
Type: "success",
Category: "Security",
},
},
{
cv: ContainerValidation{
ResourceValidation: &ResourceValidation{},
Container: &corev1.Container{Name: "", SecurityContext: &corev1.SecurityContext{
RunAsUser: &nonRootUser,
}},
},
message: ResultMessage{
ID: "runAsRootAllowed",
Message: "Is not allowed to run as root",
Type: "success",
Category: "Security",
},
},
{
cv: ContainerValidation{
ResourceValidation: &ResourceValidation{},
Container: &corev1.Container{Name: "", SecurityContext: &corev1.SecurityContext{}},
parentPodSpec: corev1.PodSpec{
SecurityContext: &corev1.PodSecurityContext{
RunAsUser: &nonRootUser,
},
},
},
message: ResultMessage{
ID: "runAsRootAllowed",
Message: "Is not allowed to run as root",
Type: "success",
Category: "Security",
},
},
{
cv: ContainerValidation{
ResourceValidation: &ResourceValidation{},
Container: &corev1.Container{Name: "", SecurityContext: &corev1.SecurityContext{
RunAsUser: &rootUser,
}},
parentPodSpec: corev1.PodSpec{
SecurityContext: &corev1.PodSecurityContext{
RunAsUser: &nonRootUser,
},
},
},
message: ResultMessage{
ID: "runAsRootAllowed",
Message: "Should not be allowed to run as root",
Type: "warning",
Category: "Security",
},
},
{
cv: ContainerValidation{
ResourceValidation: &ResourceValidation{},
Container: &corev1.Container{Name: "", SecurityContext: &corev1.SecurityContext{
RunAsNonRoot: &falseVar,
}},
parentPodSpec: corev1.PodSpec{
SecurityContext: &corev1.PodSecurityContext{
RunAsUser: &nonRootUser,
},
},
},
message: ResultMessage{
ID: "runAsRootAllowed",
Message: "Should not be allowed to run as root",
Type: "warning",
Category: "Security",
},
},
}
for idx, tt := range testCases {
tt.cv.validateSecurity(&config, "")
assert.Len(t, tt.cv.messages(), 1)
assert.Equal(t, &tt.message, tt.cv.messages()[0], fmt.Sprintf("Test case %d failed", idx))
}
}

func TestValidateResourcesExemption(t *testing.T) {
container := corev1.Container{
Name: "Empty",
Expand Down

0 comments on commit 5b7b039

Please sign in to comment.