tenable / terrascan

Detect compliance and security violations across Infrastructure as Code to mitigate risk before provisioning cloud native infrastructure.
https://runterrascan.io
Apache License 2.0
4.65k stars 495 forks source link

Kubernetes CronJob Security Context not detected #1351

Open morelser opened 2 years ago

morelser commented 2 years ago

Description

Terrascan detects a policy violation for missing Security context in a "kubernetes_cron_job" resource definition. Reference ID AC-K8-NS-PO-M-0122

What I Did

Copy the example resource definition for a kubernetes_cron_job from the Terraform documentation and add the security_context in the container spec.

resource "kubernetes_cron_job" "demo" {
  metadata {
    name = "demo"
  }
  spec {
    concurrency_policy            = "Replace"
    failed_jobs_history_limit     = 5
    schedule                      = "1 0 * * *"
    starting_deadline_seconds     = 10
    successful_jobs_history_limit = 10
    job_template {
      metadata {}
      spec {
        backoff_limit              = 2
        ttl_seconds_after_finished = 10
        template {
          metadata {}
          spec {
            security_context {
              runAsNonRoot = true
              runAsUser    = 1000
              runAsGroup   = 1000
              fsGroup      = 1000
            }
            container {
              name    = "hello"
              image   = "busybox"
              command = ["/bin/sh", "-c", "date; echo Hello from the Kubernetes cluster"]
            }
          }
        }
      }
    }
  }
}

Run terrascan and see policy violation in the scan summary.

> terrascan scan

Scan Errors -

        IaC Type            :   arm
        Directory           :   /home/<user>/cronjob_terrascan
        Error Message       :   ARM files not found in the directory /home/<user>/cronjob_terrascan

        -----------------------------------------------------------------------

        IaC Type            :   docker
        Directory           :   /home/<user>/cronjob_terrascan
        Error Message       :   Dockerfile not found in the directory /home/<user>/cronjob_terrascan

        -----------------------------------------------------------------------

        IaC Type            :   cft
        Directory           :   /home/<user>/cronjob_terrascan
        Error Message       :   cft files not found in the directory /home/<user>/cronjob_terrascan

        -----------------------------------------------------------------------

        IaC Type            :   k8s
        Directory           :   /home/<user>/cronjob_terrascan
        Error Message       :   kubernetes files not found in the directory /home/<user>/cronjob_terrascan

        -----------------------------------------------------------------------

        IaC Type            :   kustomize
        Directory           :   /home/<user>/cronjob_terrascan
        Error Message       :   kustomization.y(a)ml file not found in the directory /home/<user>/cronjob_terrascan

        -----------------------------------------------------------------------

        IaC Type            :   helm
        Directory           :   /home/<user>/cronjob_terrascan
        Error Message       :   no helm charts found in directory /home/<user>/cronjob_terrascan

        -----------------------------------------------------------------------

Violation Details -

        Description    :        Apply Security Context to Your Pods and Containers
        File           :        main.tf
        Module Name    :        root
        Plan Root      :        ./
        Line           :        1
        Severity       :        MEDIUM
        -----------------------------------------------------------------------

Scan Summary -

        File/Folder         :   /home/<user>/cronjob_terrascan
        IaC Type            :   terraform
        Scanned At          :   2022-08-02 09:29:27.963600408 +0000 UTC
        Policies Validated  :   43
        Violated Policies   :   1
        Low                 :   0
        Medium              :   1
        High                :   0

Running terrascan with log level set to debug shows this:

...
2022-08-02T11:32:32.539+0200    debug   opa/engine.go:382       query executed but found no violations{ 27 0  <nil>} {rule 15 0 'AC-K8-IA-PO-M-0141' <nil>}
2022-08-02T11:32:32.541+0200    debug   opa/engine.go:460       violation found for rule with rego{rego 15 0 
package accurics

securityContextUsed[pod.id] {
    pod := input.kubernetes_pod[_]
    container := pod.config.spec.containers[_]
    not container.securityContext
}

securityContextUsed[pod.id] {
    pod := input.kubernetes_pod[_]
    initcontainer := pod.config.spec.initContainers[_]
    not initcontainer.securityContext
}

securityContextUsed[pod.id] {
    pod := input.kubernetes_pod[_]
    not pod.config.spec.securityContext
}

securityContextUsed[pod.id] {
    pod := input.kubernetes_cron_job[_]
    container := pod.config.spec.jobTemplate.spec.template.spec.containers[_]
    not container.securityContext
}

securityContextUsed[pod.id] {
    pod := input.kubernetes_cron_job[_]
    initcontainer := pod.config.spec.jobTemplate.spec.template.spec.initContainers[_]
    not initcontainer.securityContext
}

securityContextUsed[pod.id] {
    pod := input.kubernetes_cron_job[_]
    not pod.config.spec.jobTemplate.spec.template.spec.securityContext
}

securityContextUsed[pod.id] {
    item_list := [
        object.get(input, "kubernetes_daemonset", "undefined"),
        object.get(input, "kubernetes_deployment", "undefined"),
        object.get(input, "kubernetes_job", "undefined"),
        object.get(input, "kubernetes_replica_set", "undefined"),
        object.get(input, "kubernetes_replication_controller", "undefined"),
        object.get(input, "kubernetes_stateful_set", "undefined"),
        object.get(input, "kubernetes_cron_job", "undefined")
    ]

    item = item_list[_]
    item != "undefined"

    pod := item[_]
    checkPod(pod)
}

securityContextUsed[pod.id] {
    item_list := [
        object.get(input, "kubernetes_daemonset", "undefined"),
        object.get(input, "kubernetes_deployment", "undefined"),
        object.get(input, "kubernetes_job", "undefined"),
        object.get(input, "kubernetes_replica_set", "undefined"),
        object.get(input, "kubernetes_replication_controller", "undefined"),
        object.get(input, "kubernetes_stateful_set", "undefined"),
        object.get(input, "kubernetes_cron_job", "undefined")
    ]

    item = item_list[_]
    item != "undefined"

    pod := item[_]
    checkInitContainer(pod.config.spec.template.spec)
}

securityContextUsed[pod.id] {
    item_list := [
        object.get(input, "kubernetes_daemonset", "undefined"),
        object.get(input, "kubernetes_deployment", "undefined"),
        object.get(input, "kubernetes_job", "undefined"),
        object.get(input, "kubernetes_replica_set", "undefined"),
        object.get(input, "kubernetes_replication_controller", "undefined"),
        object.get(input, "kubernetes_stateful_set", "undefined"),
        object.get(input, "kubernetes_cron_job", "undefined")
    ]

    item = item_list[_]
    item != "undefined"

    pod := item[_]
    checkContainer(pod.config.spec.template.spec)
}

checkContainer(spec) {
    containers := spec.containers[_]
    not containers.securityContext
}

checkInitContainer(spec) {
    containers := spec.initContainers[_]
    not containers.securityContext
}

checkPod(pod) {
    not pod.config.spec.template.spec.securityContext
}
 <nil>}
...
morelser commented 2 years ago

Fixed, it was a formatting error in the Security context block. Terraform expects snake_case and Kubernetes uses camelCase.

...
            security_context {
              run_as_non_root = true
              run_as_user     = 1000
              run_as_group    = 1000
              fs_group        = 1000
            }
...
morelser commented 2 years ago

Hello, I'm re-opening because the fix works for deploying the cronJob, the securityContext is applied. But terrascan still fails to recognize the security_context block.