← Policy catalog
</> ValidatingAdmissionPolicy · Apache-2.0

Runs With an Unconfined Seccomp Profile

initcontainer-seccomp-profile

severityModerate resourceInitContainers productKubernetes bundles2

An Unconfined seccomp profile removes the syscall filter from the init container, exposing the full kernel syscall surface including the obscure calls that container escape and privilege-escalation exploits depend on.

Rejects unless

(has(object.spec.os) &&
 has(object.spec.os.name) &&
 object.spec.os.name.lowerAscii() == "windows") ||
!has(object.spec.initContainers) || object.spec.initContainers.all(ic,
  !has(ic.securityContext) ||
  !has(ic.securityContext.seccompProfile) ||
  !has(ic.securityContext.seccompProfile.type) ||
  variables.allowedSeccompTypes.exists(t, t == ic.securityContext.seccompProfile.type)
)

spec.initContainers[*].securityContext.seccompProfile.type must be undefined, RuntimeDefault, or Localhost.

Variables

allowedSeccompTypes

["RuntimeDefault","Localhost"]

Remediation

Replace Unconfined with RuntimeDefault, or with Localhost naming a profile loaded on the node. Field: spec.initContainers[*].securityContext.seccompProfile.type.

Applies to

  • pods · v1 · CREATE, UPDATE

Manifest

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
  name: initcontainer-seccomp-profile
  annotations:
    kubeapt.io/uuid: "1d1a7bed-e513-42e9-9089-0e9ac08c562c"
    security.kubeapt.io/displayName: "Runs With an Unconfined Seccomp Profile"
    security.kubeapt.io/description: "An Unconfined seccomp profile removes the syscall filter from the init container, exposing the full kernel syscall surface including the obscure calls that container escape and privilege-escalation exploits depend on."
    security.kubeapt.io/resource: "InitContainers"
    security.kubeapt.io/severity: "Moderate"
    security.kubeapt.io/remediation: "Replace Unconfined with RuntimeDefault, or with Localhost naming a profile loaded on the node. Field: spec.initContainers[*].securityContext.seccompProfile.type."
    security.kubeapt.io/product: "Kubernetes"
spec:
  failurePolicy: Fail
  matchConstraints:
    resourceRules:
    - apiGroups:
      - ''
      apiVersions:
      - v1
      operations:
      - CREATE
      - UPDATE
      resources:
      - pods
  variables:
  - name: allowedSeccompTypes
    expression: |
      ["RuntimeDefault","Localhost"]
  validations:
  - expression: |
      (has(object.spec.os) &&
       has(object.spec.os.name) &&
       object.spec.os.name.lowerAscii() == "windows") ||
      !has(object.spec.initContainers) || object.spec.initContainers.all(ic,
        !has(ic.securityContext) ||
        !has(ic.securityContext.seccompProfile) ||
        !has(ic.securityContext.seccompProfile.type) ||
        variables.allowedSeccompTypes.exists(t, t == ic.securityContext.seccompProfile.type)
      )
    message: |
      spec.initContainers[*].securityContext.seccompProfile.type must be undefined, RuntimeDefault, or Localhost.

Save it as initcontainer-seccomp-profile.yaml — the commands below assume that name.

Validate with kubeapt

Check a workload against this one policy, before anything is installed on a cluster.

$ kubeapt validate -p ./initcontainer-seccomp-profile.yaml -r ./workload.yaml

Or without the file, from the published policy set — -r takes a directory too:

$ kubeapt policies download && kubeapt validate --policy-name initcontainer-seccomp-profile -r ./manifests

Or against every namespace in the cluster your kubeconfig points at:

$ kubeapt validate --policy-name initcontainer-seccomp-profile -A