Skip to content

[REVIEW] container-security: add CronJob and rendered manifest coverage gates #204

@GiazaiGia

Description

@GiazaiGia

Skill Being Reviewed

Skill name: container-security
Skill path: skills/cloud/container-security/

False Positive Analysis

Benign code that triggers a false positive:

# kustomize base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  template:
    spec:
      containers:
        - name: api
          image: ghcr.io/example/api@sha256:1111111111111111111111111111111111111111111111111111111111111111
          # Security context is intentionally injected by the production overlay.
---
# kustomize overlays/prod/patch-security-context.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  template:
    spec:
      securityContext:
        runAsNonRoot: true
        seccompProfile:
          type: RuntimeDefault
      containers:
        - name: api
          securityContext:
            runAsUser: 65532
            runAsGroup: 65532
            runAsNonRoot: true
            allowPrivilegeEscalation: false
            readOnlyRootFilesystem: true
            capabilities:
              drop: ["ALL"]

Why this is a false positive:

The current skill tells reviewers to inspect Dockerfiles, Kubernetes manifests, Helm charts, Kustomize overlays, and values files, but it does not require reviewers to produce or inspect the rendered/merged workload that is actually applied to the cluster. If the base manifest is reviewed in isolation, the workload appears to be missing runAsNonRoot, allowPrivilegeEscalation: false, dropped capabilities, and seccomp. In production, the Kustomize overlay applies those controls. A source review should still note that the base is incomplete, but the security finding should be based on the final rendered manifest for the environment under review.

Coverage Gaps

Missed variant 1: CronJob and Job pod templates can hide the same high-risk pod settings

apiVersion: batch/v1
kind: CronJob
metadata:
  name: nightly-export
spec:
  schedule: "0 2 * * *"
  jobTemplate:
    spec:
      template:
        spec:
          serviceAccountName: default
          containers:
            - name: exporter
              image: ghcr.io/example/exporter:latest
              securityContext:
                privileged: true
                allowPrivilegeEscalation: true
              volumeMounts:
                - name: docker-sock
                  mountPath: /var/run/docker.sock
          volumes:
            - name: docker-sock
              hostPath:
                path: /var/run/docker.sock
          restartPolicy: OnFailure

Why it should be caught:

The main SKILL.md output format and resource examples focus on Deployment/StatefulSet-style workloads. The detailed benchmark file mentions Jobs and CronJobs later, but the main discovery/reporting flow does not force traversal of nested pod specs under spec.jobTemplate.spec.template.spec. A privileged CronJob with a Docker socket hostPath can be just as severe as a privileged Deployment because the created Job pods still run with the same runtime privileges and service account.

Missed variant 2: Helm/Kustomize rendering can introduce dangerous settings that are absent from source templates

# charts/api/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  template:
    spec:
      containers:
        - name: api
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          securityContext:
{{ toYaml .Values.securityContext | indent 12 }}
---
# charts/api/values-prod.yaml
image:
  repository: ghcr.io/example/api
  tag: latest
securityContext:
  privileged: true
  allowPrivilegeEscalation: true
  capabilities:
    add: ["SYS_ADMIN"]

Why it should be caught:

A raw Helm template can look neutral or safe while the environment-specific values file renders it into a privileged workload. The current skill says Helm values may override security settings, but it does not require reviewers to run or request helm template / kustomize build, identify the selected values/overlay, and attach the rendered manifest as evidence. That leaves an important false-negative path for production-only insecure settings.

Edge Cases

  • Pod, Deployment, StatefulSet, DaemonSet, ReplicaSet, ReplicationController, Job, and CronJob all place pod specs at different paths; the review should normalize these to a common workload/pod-template model before applying Pod Security checks.
  • A suspended CronJob (spec.suspend: true) still deserves a finding if it will be resumed with unsafe settings, but severity may differ from an actively scheduled job.
  • Helm charts often have multiple values files. The review should state which values file or release configuration was assessed instead of treating chart defaults as production truth.
  • Kustomize strategic merge and JSON6902 patches can both add and remove security controls. Reviewing only the base or only the patch is insufficient evidence.
  • Generated manifests should preserve enough source mapping to point maintainers back to the template/values/overlay that introduced the risky field.

Remediation Quality

  • Fix resolves the vulnerability
  • Fix doesn't introduce new security issues
  • Fix doesn't break functionality
  • Issues found: Existing remediation guidance is strong for direct Kubernetes manifests, non-root users, dropped capabilities, network policies, and read-only filesystems. It should add a render/merge step for Helm and Kustomize, plus a normalized workload traversal table so remediation applies to CronJobs and Jobs as consistently as Deployments.

Comparison to Other Tools

Tool Catches this? Notes
Semgrep Partial Can match YAML paths, but rules must explicitly include spec.jobTemplate.spec.template.spec and rendered chart output to avoid misses.
CodeQL No CodeQL is not normally used for Kubernetes workload-template traversal or Helm/Kustomize render validation.
Other: kube-linter / kube-score / Polaris / Checkov Partial These tools can catch many unsafe pod fields after manifests are rendered, but they still depend on feeding the correct Helm values or Kustomize overlay.

Overall Assessment

Strengths:

  • Strong framework mapping to CIS Docker, CIS Kubernetes, NIST SP 800-190, and Pod Security Standards.
  • Good coverage of privileged containers, host namespaces, hostPath volumes, wildcard RBAC, network policies, secrets, and runtime hardening.
  • The common pitfalls already acknowledge that init containers, sidecars, Helm values, and Kustomize overlays matter.

Needs improvement:

  • The main workflow should require final rendered manifests for Helm/Kustomize when chart/overlay inputs are present.
  • The output format should explicitly support Job and CronJob resources and nested pod-template paths.
  • The evidence model should identify both the rendered manifest field and the source template/values/patch responsible for it.

Priority recommendations:

  1. Add a render step: run or request helm template and/or kustomize build for each reviewed environment, then base security findings on the rendered manifests.
  2. Add a workload traversal table for Pod, Deployment, StatefulSet, DaemonSet, ReplicaSet, ReplicationController, Job, and CronJob pod-spec paths.
  3. Update the report template with Rendered source, Workload kind, Pod spec path, and Source template/values/patch fields so reviewers can give actionable evidence.

Bounty Info

  • I have read and agree to the CONTRIBUTING.md bounty terms
  • Preferred payment method: Payment details can be provided privately after acceptance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions