Skip to content

Commit 41071a5

Browse files
Add OpenShift SecurityContextConstraints object linting (#650)
Co-authored-by: Cereberus <[email protected]>
1 parent 238ec49 commit 41071a5

File tree

14 files changed

+400
-1
lines changed

14 files changed

+400
-1
lines changed

docs/generated/checks.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,21 @@ key: owner
513513
**Remediation**: Set runAsUser to a non-zero number and runAsNonRoot to true in your pod or container securityContext. Refer to https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ for details.
514514
515515
**Template**: [run-as-non-root](templates.md#run-as-non-root-user)
516+
## scc-deny-privileged-container
517+
518+
**Enabled by default**: No
519+
520+
**Description**: Indicates when allowPrivilegedContainer SecurityContextConstraints set to true
521+
522+
**Remediation**: SecurityContextConstraints has AllowPrivilegedContainer set to "true". Using this option is dangerous, please consider using allowedCapabilities instead. Refer to https://docs.openshift.com/container-platform/4.12/authentication/managing-security-context-constraints.html#scc-settings_configuring-internal-oauth for details.
523+
524+
**Template**: [scc-deny-privileged-container](templates.md#securitycontextconstraints-allowprivilegedcontainer)
525+
526+
**Parameters**:
527+
528+
```yaml
529+
AllowPrivilegedContainer: true
530+
```
516531
## sensitive-host-mounts
517532
518533
**Enabled by default**: Yes

docs/generated/templates.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,24 @@ KubeLinter supports the following templates:
694694
**Supported Objects**: DeploymentLike
695695

696696

697+
## SecurityContextConstraints allowPrivilegedContainer
698+
699+
**Key**: `scc-deny-privileged-container`
700+
701+
**Description**: Flag SCC with allowPrivilegedContainer set to true
702+
703+
**Supported Objects**: SecurityContextConstraints
704+
705+
706+
**Parameters**:
707+
708+
```yaml
709+
- description: allowPrivilegedContainer value
710+
name: allowPrivilegedContainer
711+
required: false
712+
type: boolean
713+
```
714+
697715
## Service Account
698716

699717
**Key**: `service-account`

e2etests/bats-tests.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -739,6 +739,21 @@ get_value_from() {
739739
[[ "${count}" == "2" ]]
740740
}
741741

742+
@test "scc-deny-privileged-container" {
743+
tmp="tests/checks/scc-deny-privileged-container.yml"
744+
cmd="${KUBE_LINTER_BIN} lint --include scc-deny-privileged-container --do-not-auto-add-defaults --format json ${tmp}"
745+
run ${cmd}
746+
747+
print_info "${status}" "${output}" "${cmd}" "${tmp}"
748+
[ "$status" -eq 1 ]
749+
750+
message1=$(get_value_from "${lines[0]}" '.Reports[0].Object.K8sObject.GroupVersionKind.Kind + ": " + .Reports[0].Diagnostic.Message')
751+
count=$(get_value_from "${lines[0]}" '.Reports | length')
752+
753+
[[ "${message1}" == "SecurityContextConstraints: SCC has allowPrivilegedContainer set to true" ]]
754+
[[ "${count}" == "1" ]]
755+
}
756+
742757
@test "sensitive-host-mounts" {
743758
tmp="tests/checks/sensitive-host-mounts.yml"
744759
cmd="${KUBE_LINTER_BIN} lint --include sensitive-host-mounts --do-not-auto-add-defaults --format json ${tmp}"
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name: "scc-deny-privileged-container"
2+
description: "Indicates when allowPrivilegedContainer SecurityContextConstraints set to true"
3+
remediation: >-
4+
SecurityContextConstraints has AllowPrivilegedContainer set to "true". Using this option is dangerous, please consider using allowedCapabilities instead. Refer to https://docs.openshift.com/container-platform/4.12/authentication/managing-security-context-constraints.html#scc-settings_configuring-internal-oauth for details.
5+
scope:
6+
objectKinds:
7+
- SecurityContextConstraints
8+
template: "scc-deny-privileged-container"
9+
params:
10+
AllowPrivilegedContainer: true

pkg/extract/scc_spec.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package extract
2+
3+
import (
4+
ocpSecV1 "github.com/openshift/api/security/v1"
5+
"golang.stackrox.io/kube-linter/pkg/k8sutil"
6+
)
7+
8+
// SCCallowPrivilegedContainer extracts allowPrivilegedContainer from the given object, if available.
9+
func SCCallowPrivilegedContainer(obj k8sutil.Object) (bool, bool) {
10+
if scc, ok := obj.(*ocpSecV1.SecurityContextConstraints); ok {
11+
return scc.AllowPrivilegedContainer, true
12+
}
13+
return false, false
14+
}

pkg/lintcontext/mocks/scc.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package mocks
2+
3+
import (
4+
"testing"
5+
6+
ocpSecV1 "github.com/openshift/api/security/v1"
7+
"github.com/stretchr/testify/require"
8+
"golang.stackrox.io/kube-linter/pkg/objectkinds"
9+
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
)
11+
12+
// AddMockSecurityContextConstraints adds a mock SecurityContextConstraints to LintContext
13+
func (l *MockLintContext) AddMockSecurityContextConstraints(t *testing.T, name string, allowFlag bool) {
14+
require.NotEmpty(t, name)
15+
l.objects[name] = &ocpSecV1.SecurityContextConstraints{
16+
TypeMeta: metaV1.TypeMeta{
17+
Kind: objectkinds.SecurityContextConstraints,
18+
APIVersion: objectkinds.GetSCCAPIVersion(),
19+
},
20+
ObjectMeta: metaV1.ObjectMeta{Name: name},
21+
AllowPrivilegedContainer: allowFlag,
22+
}
23+
}

pkg/lintcontext/parse_yaml.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
y "github.com/ghodss/yaml"
1414
ocsAppsV1 "github.com/openshift/api/apps/v1"
15+
ocpSecV1 "github.com/openshift/api/security/v1"
1516
"github.com/pkg/errors"
1617
k8sMonitoring "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
1718
"golang.stackrox.io/kube-linter/pkg/k8sutil"
@@ -42,7 +43,7 @@ func init() {
4243
clientScheme := scheme.Scheme
4344

4445
// Add OpenShift and Autoscaling schema
45-
schemeBuilder := runtime.NewSchemeBuilder(ocsAppsV1.AddToScheme, autoscalingV2Beta1.AddToScheme, k8sMonitoring.AddToScheme)
46+
schemeBuilder := runtime.NewSchemeBuilder(ocsAppsV1.AddToScheme, autoscalingV2Beta1.AddToScheme, k8sMonitoring.AddToScheme, ocpSecV1.AddToScheme)
4647
if err := schemeBuilder.AddToScheme(clientScheme); err != nil {
4748
panic(fmt.Sprintf("Can not add OpenShift schema %v", err))
4849
}

pkg/objectkinds/securitycontext.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package objectkinds
2+
3+
import (
4+
ocpSecV1 "github.com/openshift/api/security/v1"
5+
"k8s.io/apimachinery/pkg/runtime/schema"
6+
)
7+
8+
const (
9+
// Service represents Kubernetes Service objects.
10+
SecurityContextConstraints = "SecurityContextConstraints"
11+
)
12+
13+
var (
14+
sccGVK = ocpSecV1.SchemeGroupVersion.WithKind("SecurityContextConstraints")
15+
)
16+
17+
func init() {
18+
RegisterObjectKind(SecurityContextConstraints, MatcherFunc(func(gvk schema.GroupVersionKind) bool {
19+
return gvk == sccGVK
20+
}))
21+
}
22+
23+
// GetSCCAPIVersion returns SCC's apiversion
24+
func GetSCCAPIVersion() string {
25+
return sccGVK.GroupVersion().String()
26+
}

pkg/templates/all/all.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ import (
4646
_ "golang.stackrox.io/kube-linter/pkg/templates/requiredannotation"
4747
_ "golang.stackrox.io/kube-linter/pkg/templates/requiredlabel"
4848
_ "golang.stackrox.io/kube-linter/pkg/templates/runasnonroot"
49+
_ "golang.stackrox.io/kube-linter/pkg/templates/sccdenypriv"
4950
_ "golang.stackrox.io/kube-linter/pkg/templates/serviceaccount"
5051
_ "golang.stackrox.io/kube-linter/pkg/templates/servicetype"
5152
_ "golang.stackrox.io/kube-linter/pkg/templates/sysctl"

pkg/templates/sccdenypriv/internal/params/gen-params.go

Lines changed: 69 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)