静的解析ツールを使ってHelm Chartを解析する
はじめに
アプリケーションコードと比べて、Helm Chart など IaC のテストコードを書く機会は少ないと思います。そのためレビュー時に、yaml ファイルの設定を見落とす、といった懸念があります。
こういった懸念を解消する手段として静的解析ツールがあります。
業務で Helm Chart を静的解析してみたので、学んだことを書いていきます。
使用する解析ツール
今回使ってみた静的解析ツールは以下の3つです。
- Trivy
- Kics
- Checkov
選定理由は以下の通りです。
-
静的解析に API key を前提としないこと CI やローカルで実行することを前提としており、API key の発行や管理で導入のハードルが上がる可能性があるためです。 たとえば、snyk(スニーク) は、CLI を使用するために API key を設定する必要があります。
Terminal window $ helm create example$ helm template example --output-dir ./output$ snyk iac test output`snyk` requires an authenticated account. Please run `snyk auth` and try again. -
解析項目が多いこと 解析項目の数が少ないと、自分たちで解析項目を作成、メンテナンスをする必要があるためです。
Trivy
Terminal window $ git clone https://github.com/aquasecurity/defsec.git$ cd defsec$ git checkout v0.90.3$ find rules/kubernetes/policies -regex ".*.rego" -not -regex ".*_test.rego" | wc -l153# cisbenchmarks ディレクトリは apiserver や cni などの解析をする設定のようなので、解析項目数から外してみる# https://github.com/aquasecurity/defsec/tree/v0.90.3/rules/kubernetes/policies/cisbenchmarks$ find rules/kubernetes/policies -regex ".*.rego" -not -regex ".*_test.rego" -not -regex ".*cisbenchmarks.*" | wc -l64Kics
Terminal window $ docker run --rm --entrypoint="" checkmarx/kics:latest sh -c "find assets/queries/k8s/ -name *.json" | wc -l146Checkov
Terminal window $ checkov -l | grep CKV_K8S | cut -d \| -f 3 | uniq | wc -l112 -
カスタムした解析項目を追加できること 組織やチームによっては解析項目を追加したい場合があると思います。その場合、解析項目を自分たちでカスタマイズする必要が出てくる可能性があるためです。
-
定期的にメンテナンスがされていること 解析項目の追加や修正が行われていない場合、自分たちで脆弱性などの情報をキャッチアップし、かつ解析項目の追加をしないといけなくなるからです。
-
eslint のように、コメントを書くと指摘事項を無視することができる機能があること 解析するコードによっては、修正する必要のない項目があり、何もしないと指摘され続けます。
そのため細かく解析項目を制御したいケースがあると嬉しいと思ったからです。 Using configuration comments - eslint.org
Trivy の概要と特徴
バージョン | |
---|---|
Trivy | 0.43.1 |
defsec | v0.90.3 |
Trivy とポリシー
Trivy では、解析項目を「ポリシー」と呼び、Rego 言語でポリシーを定義しています。
具体的なポリシー定義は、aquasecurity/defsecリポジトリに記述されています。
Trivy のバージョンに対応した defsec のバージョンは、Trivyのリポジトリにあるgo.mod に記載されています。
Trivy がサポートしているプラットフォーム
Trivy では以下の IaC をサポートしています。
- Helm
- Kustomization
- Docker
- Terraform
- CloudFormation
- その他
ポリシーの重要度(severity)
各ポリシーには、以下の重要度(severity)が割り当てられています。ポリシーをフィルタリングをコマンドのオプションで設定できます。(例: severity: CRITICAL
のみ解析に使用する)
CRITICAL
HIGH
MEDIUM
LOW
UNKNOWN
Terraform や Helm の解析オプション
とくに Terraform や Helm の解析では、変数を上書きできるオプションが存在します。これにより、特定の値を上書きして解析することが可能です。ただし、Kics にこのようなオプションはありません。
Terraform における変数の上書きに関する詳細は、こちらのドキュメントを参照してください。
$ trivy conf -h
...
Misconfiguration Flags --helm-set strings specify Helm values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-set-file strings specify Helm values from respective files specified via the command line (can specify multiple or separate values with commas: key1=path1,key2=path2) --helm-set-string strings specify Helm string values on the command line (can specify multiple or separate values with commas: key1=val1,key2=val2) --helm-values strings specify paths to override the Helm values.yaml files --include-non-failures include successes and exceptions, available with '--scanners config' --reset-policy-bundle remove policy bundle --tf-vars strings specify paths to override the Terraform tfvars files
...
Trivy ができないこと
trivy conf
コマンドでできないことを紹介します。
-
特定のクエリのみ解析に使用することはできない
.trivyignore
ファイルを作成することで、解析に使用するポリシーを除外できます。しかし、あらかじめ用意されたポリシーを CLI のオプションに指定して解析に使用することはできません By Finding IDs -
CLI のオプションで、特定のポリシーを解析から外すことはできない
--exclude-policies
のようなオプションはありません。.trivyignore
ファイルでしか実現できません。 -
コメントを使用したポリシーのフィルタリング By Inline Comments のページでは、コードにインラインコメント(
#trivy:ignore:
)を書くことでポリシーのフィルターが可能である旨が書いてありますが、手元の Helm Chart で試したところ機能しませんでした。2023年8月現在、以下の Issue が Open のままでしたが、将来的にはできそうです。 Support Inline Filtering #2961
-
Helm Chart を解析対象に指定した場合、拡張子
yml
は解析できない 拡張子がyaml
なら解析できます -
ポリシーの一覧を表示するCLI のコマンドはない
Trivyのポリシーの一覧をテーブル形式で取得する
CLI のオプションが存在しないので、defsec のリポジトリから shell で取り出します。
以下のコマンドは severity: CRITICAL
である Kubernetes のポリシーの一覧をマークダウン形式のテーブルで作成できます。
$ git clone https://github.com/aquasecurity/defsec.git$ cd defsec$ git checkout v0.90.3
$ git grep --name-only "severity: CRITICAL" -- ':!**/cisbenchmarks/**' rules/kubernetes/policies/ | xargs grep -E "(\s)id: |(\s)avd_id: |title|description" | sed 's/"//g' | awk -F : '{ if($2 == "# avd_id") { printf "[%s](https://github.com/aquasecurity/defsec/tree/v0.90.3/%s)\n",$3 ,$1} else {printf "%s # ", $3} }' | awk -F # '{printf "| %s | %s | %s | %s | \n", $3, $4, $1, $2 }'
出力結果
| KSV044 | [ AVD-KSV-0044](https://github.com/aquasecurity/defsec/tree/v0.90.3/rules/kubernetes/policies/general/any_any.rego) | No wildcard verb and resource roles | [ Check whether role permits wildcard verb on wildcard resource || KSV046 | [ AVD-KSV-0046](https://github.com/aquasecurity/defsec/tree/v0.90.3/rules/kubernetes/policies/general/any_resource.rego) | No wildcard resource roles | [ Check whether role permits specific verb on wildcard resources || KSV045 | [ AVD-KSV-0045](https://github.com/aquasecurity/defsec/tree/v0.90.3/rules/kubernetes/policies/general/any_verb.rego) | No wildcard verb roles | [ Check whether role permits wildcard verb on specific resources || KSV043 | [ AVD-KSV-0043](https://github.com/aquasecurity/defsec/tree/v0.90.3/rules/kubernetes/policies/general/impersonate_privileged_groups.rego) | Do not allow impersonation of privileged groups | [ Check whether role permits impersonating privileged groups || KSV050 | [ AVD-KSV-0050](https://github.com/aquasecurity/defsec/tree/v0.90.3/rules/kubernetes/policies/general/manage_kubernetes_rbac_resources.rego) | Do not allow management of RBAC resources | [ An effective level of access equivalent to cluster-admin should not be provided. || KSV041 | [ AVD-KSV-0041](https://github.com/aquasecurity/defsec/tree/v0.90.3/rules/kubernetes/policies/general/manage_secrets.rego) | Do not allow management of secrets | [ Check whether role permits managing secrets || KSV102 | [ AVD-KSV-0102](https://github.com/aquasecurity/defsec/tree/v0.90.3/rules/kubernetes/policies/general/tiller_is_deployed.rego) | Tiller Is Deployed | [ Check if Helm Tiller component is deployed. |
テーブルのヘッダーは自分で作成する必要がありますが、ヘッダーのすぐ下に、先ほどの git grep
コマンドの結果をコピペすると、以下のような見た目になります。
ヘッダー
| id | avd_id | title | description ||--|--|--|--|
完成した severity: CRITICAL
である Kubernetes のポリシー一覧
id | avd_id | title | description |
---|---|---|---|
KSV044 | AVD-KSV-0044 | No wildcard verb and resource roles | Check whether role permits wildcard verb on wildcard resource |
KSV046 | AVD-KSV-0046 | No wildcard resource roles | Check whether role permits specific verb on wildcard resources |
KSV045 | AVD-KSV-0045 | No wildcard verb roles | Check whether role permits wildcard verb on specific resources |
KSV043 | AVD-KSV-0043 | Do not allow impersonation of privileged groups | Check whether role permits impersonating privileged groups |
KSV050 | AVD-KSV-0050 | Do not allow management of RBAC resources | An effective level of access equivalent to cluster-admin should not be provided. |
KSV041 | AVD-KSV-0041 | Do not allow management of secrets | Check whether role permits managing secrets |
KSV102 | AVD-KSV-0102 | Tiller Is Deployed | Check if Helm Tiller component is deployed. |
Trivy 使い方
Kubernetes のマニフェストは helm を使います。
基本的な使い方
trivy conf <DIR>
で実行します。
$ helm create example$ trivy conf example
"trivy conf example" の出力結果
$ trivy conf exampletemplates/deployment.yaml (helm)
Tests: 141 (SUCCESSES: 129, FAILURES: 12, EXCEPTIONS: 0)Failures: 12 (UNKNOWN: 0, LOW: 10, MEDIUM: 2, HIGH: 0, CRITICAL: 0)
MEDIUM: Container 'example' of Deployment 'example' should set 'securityContext.allowPrivilegeEscalation' to false══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════A program inside the container can elevate its own privileges and run as root, which might give the program control over the container and node.
See https://avd.aquasec.com/misconfig/ksv001────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── templates/deployment.yaml:28-46────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 28 ┌ - name: example 29 │ securityContext: 30 │ {} 31 │ image: "nginx:1.16.0" 32 │ imagePullPolicy: IfNotPresent 33 │ ports: 34 │ - name: http 35 │ containerPort: 80 36 └ protocol: TCP ..──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
LOW: Container 'example' of Deployment 'example' should add 'ALL' to 'securityContext.capabilities.drop'══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════The container should drop all default capabilities and add only those that are needed for its execution.
See https://avd.aquasec.com/misconfig/ksv003────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── templates/deployment.yaml:28-46────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 28 ┌ - name: example 29 │ securityContext: 30 │ {} 31 │ image: "nginx:1.16.0" 32 │ imagePullPolicy: IfNotPresent 33 │ ports: 34 │ - name: http 35 │ containerPort: 80 36 └ protocol: TCP ..──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
LOW: Container 'example' of Deployment 'example' should set 'resources.limits.cpu'══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════Enforcing CPU limits prevents DoS via resource exhaustion.
See https://avd.aquasec.com/misconfig/ksv011────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── templates/deployment.yaml:28-46────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 28 ┌ - name: example 29 │ securityContext: 30 │ {} 31 │ image: "nginx:1.16.0" 32 │ imagePullPolicy: IfNotPresent 33 │ ports: 34 │ - name: http 35 │ containerPort: 80 36 └ protocol: TCP ..──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
MEDIUM: Container 'example' of Deployment 'example' should set 'securityContext.runAsNonRoot' to true══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════'runAsNonRoot' forces the running image to run as a non-root user to ensure least privileges.
See https://avd.aquasec.com/misconfig/ksv012────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── templates/deployment.yaml:28-46────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 28 ┌ - name: example 29 │ securityContext: 30 │ {} 31 │ image: "nginx:1.16.0" 32 │ imagePullPolicy: IfNotPresent 33 │ ports: 34 │ - name: http 35 │ containerPort: 80 36 └ protocol: TCP ..──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
LOW: Container 'example' of Deployment 'example' should set 'securityContext.readOnlyRootFilesystem' to true══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════An immutable root file system prevents applications from writing to their local disk. This can limit intrusions, as attackers will not be able to tamper with the file system or write foreign executables to disk.
See https://avd.aquasec.com/misconfig/ksv014────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── templates/deployment.yaml:28-46────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 28 ┌ - name: example 29 │ securityContext: 30 │ {} 31 │ image: "nginx:1.16.0" 32 │ imagePullPolicy: IfNotPresent 33 │ ports: 34 │ - name: http 35 │ containerPort: 80 36 └ protocol: TCP ..──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
LOW: Container 'example' of Deployment 'example' should set 'resources.requests.cpu'══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════When containers have resource requests specified, the scheduler can make better decisions about which nodes to place pods on, and how to deal with resource contention.
See https://avd.aquasec.com/misconfig/ksv015────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── templates/deployment.yaml:28-46────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 28 ┌ - name: example 29 │ securityContext: 30 │ {} 31 │ image: "nginx:1.16.0" 32 │ imagePullPolicy: IfNotPresent 33 │ ports: 34 │ - name: http 35 │ containerPort: 80 36 └ protocol: TCP ..──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
LOW: Container 'example' of Deployment 'example' should set 'resources.requests.memory'══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════When containers have memory requests specified, the scheduler can make better decisions about which nodes to place pods on, and how to deal with resource contention.
See https://avd.aquasec.com/misconfig/ksv016────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── templates/deployment.yaml:28-46────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 28 ┌ - name: example 29 │ securityContext: 30 │ {} 31 │ image: "nginx:1.16.0" 32 │ imagePullPolicy: IfNotPresent 33 │ ports: 34 │ - name: http 35 │ containerPort: 80 36 └ protocol: TCP ..──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
LOW: Container 'example' of Deployment 'example' should set 'resources.limits.memory'══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════Enforcing memory limits prevents DoS via resource exhaustion.
See https://avd.aquasec.com/misconfig/ksv018────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── templates/deployment.yaml:28-46────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 28 ┌ - name: example 29 │ securityContext: 30 │ {} 31 │ image: "nginx:1.16.0" 32 │ imagePullPolicy: IfNotPresent 33 │ ports: 34 │ - name: http 35 │ containerPort: 80 36 └ protocol: TCP ..──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
LOW: Container 'example' of Deployment 'example' should set 'securityContext.runAsUser' > 10000══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════Force the container to run with user ID > 10000 to avoid conflicts with the host’s user table.
See https://avd.aquasec.com/misconfig/ksv020────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── templates/deployment.yaml:28-46────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 28 ┌ - name: example 29 │ securityContext: 30 │ {} 31 │ image: "nginx:1.16.0" 32 │ imagePullPolicy: IfNotPresent 33 │ ports: 34 │ - name: http 35 │ containerPort: 80 36 └ protocol: TCP ..──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
LOW: Container 'example' of Deployment 'example' should set 'securityContext.runAsGroup' > 10000══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════Force the container to run with group ID > 10000 to avoid conflicts with the host’s user table.
See https://avd.aquasec.com/misconfig/ksv021────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── templates/deployment.yaml:28-46────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 28 ┌ - name: example 29 │ securityContext: 30 │ {} 31 │ image: "nginx:1.16.0" 32 │ imagePullPolicy: IfNotPresent 33 │ ports: 34 │ - name: http 35 │ containerPort: 80 36 └ protocol: TCP ..──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
LOW: Either Pod or Container should set 'securityContext.seccompProfile.type' to 'RuntimeDefault'══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════The RuntimeDefault/Localhost seccomp profile must be required, or allow specific additional profiles.
See https://avd.aquasec.com/misconfig/ksv030────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── templates/deployment.yaml:28-46────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 28 ┌ - name: example 29 │ securityContext: 30 │ {} 31 │ image: "nginx:1.16.0" 32 │ imagePullPolicy: IfNotPresent 33 │ ports: 34 │ - name: http 35 │ containerPort: 80 36 └ protocol: TCP ..──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
LOW: container should drop all══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════Containers must drop ALL capabilities, and are only permitted to add back the NET_BIND_SERVICE capability.
See https://avd.aquasec.com/misconfig/ksv106────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── templates/deployment.yaml:28-46────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 28 ┌ - name: example 29 │ securityContext: 30 │ {} 31 │ image: "nginx:1.16.0" 32 │ imagePullPolicy: IfNotPresent 33 │ ports: 34 │ - name: http 35 │ containerPort: 80 36 └ protocol: TCP ..──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
seveiry: CRITICAL,HIGH のポリシーを使用する
-s, --severity
オプションを使用します。
$ trivy conf --severity CRITICAL,HIGH example2023-07-25T23:36:31.486+0900 INFO Misconfiguration scanning is enabled2023-07-25T23:36:32.234+0900 INFO Detected config files: 3
Trivy の出力形式を json にする
-f, --format
オプションを使用します。
$ trivy conf --severity MEDIUM example -f json --quiet
設定できるフォーマットは以下の通りです。
- table
- json
- template
- sarif
- cyclonedx
- spdx
- spdx-json
- github
- cosign-vuln
Kics の概要と特徴
バージョン | |
---|---|
Kics | v1.7.4 |
Kicsがサポートしているプラットフォーム
Kics では以下の IaC をサポートしています。
- Terraform
- Kubernetes
- Helm
- Docker
- Ansible
- その他
Supported Platforms - docs.kics.io
Kics とクエリ
Kics では解析項目のことをクエリ
と呼び、Rego 言語で書かれています。
クエリ一覧は Query List から確認できます。
クエリの分類
Kics は Tricy や Checkov と異なり、クエリに severity
と category
という2つの分類がある点が特徴です。
--exclude-categories
、--exclude-severities
2つのオプションがあるので要件に合わせて柔軟にクエリのフィルターを実現できます。
severity
- High
- Medium
- Low
- Info
category
- Access Control
- Availability
- Backup
- Best Practices
- Build Process
- Encryption
- Insecure Configurations
- Insecure Defaults
- Networking and Firewall
- Observability
- Resource Management
- Secret Management
- Structure and Semantics
- Supply-Chain
Query Categories - docs.kics.io
exit コード
Kics は解析した結果 exit コードが変わります。そのため CI で実行に失敗したとき、exit コードに 0 以外が出ます。
コード | 説明 |
---|---|
0 | 結果がない = 異常がない |
50 | severity: High の結果がある |
40 | severity: Medium の結果がある |
30 | severity: Low の結果がある |
20 | severity: Info の結果がある |
Exit Status Code - docs.kics.io
クエリをスキップする
以下のように ignore
のコメントを書くと、解析時に特定のブロック、ファイルを解析対象から外します。
# kics-scan ignoreresource "google_storage_bucket" "example" { name = "image-store.com" location = "EU" force_destroy = true}
実際に試してみます。
Helm で example チャートを作成した後、severity: HIGH のクエリを実行します。
すると、Kics からクエリID:5572cc5e-1e4c-4113-92a6-7a8a3bd25e6d
を指摘されました。
$ helm cereate example$ docker run --rm -v $(pwd):/charts checkmarx/kics:latest scan -p /charts/example --exclude-severities info,low,medium --no-progress...
Files scanned: 4Parsed files: 3Queries loaded: 32Queries failed to execute: 0
------------------------------------
Privilege Escalation Allowed, Severity: HIGH, Results: 1Description: Containers should not run with allowPrivilegeEscalation in order to prevent them from gaining more privileges than their parent processPlatform: KubernetesLearn more about this vulnerability: https://docs.kics.io/latest/queries/kubernetes-queries/5572cc5e-1e4c-4113-92a6-7a8a3bd25e6d
[1]: ../../charts/example/templates/deployment.yaml:30
029: {{- toYaml .Values.podSecurityContext | nindent 8 }} 030: containers: 031: - name: {{ .Chart.Name }}
Results Summary:HIGH: 1MEDIUM: 0LOW: 0INFO: 0TOTAL: 1
このクエリを無視してもらうため、チャートのテンプレートにコメントを書いてみます。
apiVersion: apps/v1kind: Deploymentmetadata: ...spec: ... template: ... spec: ... # kics-scan ignore-block disable=5572cc5e-1e4c-4113-92a6-7a8a3bd25e6d containers: ...
ignore のコメントを追加したので、もう一度同じコマンドを実行してみます。
$ docker run --rm -v $(pwd):/charts checkmarx/kics:latest scan -p /charts/example --exclude-severities info,low,medium --no-progress...
Files scanned: 4Parsed files: 3Queries loaded: 32Queries failed to execute: 0
------------------------------------
Results Summary:HIGH: 0MEDIUM: 0LOW: 0INFO: 0TOTAL: 0
意図した通り、Kics に指摘されなくなりました。
Using commands on scanned files as comments - docs.kics.io
Kics ができないこと
-
Mac を開発で使用している場合、Homebrew でインストールできない 厳密には可能ですが、最新バージョンはありません。docker イメージの使用を推奨。 Installation - docs.kics.io
-
Trivy と違い、Terraform や Helm を解析する場合、オプションで値を上書きすることができない
-
Trivy と同様 CLI でクエリの一覧を取得する方法はない クエリ一覧は Query List から確認できます。
Kics のクエリ一覧をテーブル形式で取得する
Kics にはドキュメントにクエリ一覧があります。
チームによっては、README やドキュメントツールで、使用するクエリを管理したい場合もあると思ったので、サンプルの shell スクリプトを作成しました。
以下のコマンドは、カテゴリーが Secret Management
である Kubernetes のクエリをテーブル形式で出力するコマンドです。
$ for severity in {CRITICAL,HIGH,MEDIUM,LOW}; do docker run --rm --entrypoint="" checkmarx/kics:latest sh -c "find assets/queries/k8s/ -name *.json | xargs cat" | jq --arg severity $severity -r 'select(.category == "Secret Management" and .severity == $severity) | [.id, .id, .severity, .queryName, .descriptionText] | @sh' | xargs printf '[%s](https://docs.kics.io/latest/queries/kubernetes-queries/%s) | %s | %s | %s|\n'; done
出力結果
[ae8827e2-4af9-4baa-9998-87539ae0d6f0](https://docs.kics.io/latest/queries/kubernetes-queries/ae8827e2-4af9-4baa-9998-87539ae0d6f0) | HIGH | Peer Auto TLS Set To True | When using etcd commands, the '--peer-auto-tls' should be set to false|[98ce8b81-7707-4734-aa39-627c6db3d84b](https://docs.kics.io/latest/queries/kubernetes-queries/98ce8b81-7707-4734-aa39-627c6db3d84b) | HIGH | Auto TLS Set To True | When using etcd commands, the '--auto-tls' should be set to false|[9391103a-d8d7-4671-ac5d-606ba7ccb0ac](https://docs.kics.io/latest/queries/kubernetes-queries/9391103a-d8d7-4671-ac5d-606ba7ccb0ac) | MEDIUM | Etcd Client Certificate Authentication Set To False | When using etcd commands, the '--client-cert-auth' flag should be defined|[36a27826-1bf5-49da-aeb0-a60a30c0e834](https://docs.kics.io/latest/queries/kubernetes-queries/36a27826-1bf5-49da-aeb0-a60a30c0e834) | MEDIUM | Kubelet Client Certificate Or Key Not Set | When using kube-apiserver command, the 'kubelet-client-key' and 'kubelet-client-certificate' flags should be set|[ec18a0d3-0069-4a58-a7fb-fbfe0b4bbbe0](https://docs.kics.io/latest/queries/kubernetes-queries/ec18a0d3-0069-4a58-a7fb-fbfe0b4bbbe0) | MEDIUM | Kubelet Certificate Authority Not Set | When using kube-apiserver command, the 'kubelet-certificate-authority' flag should be set|[dab4ec72-ce2e-4732-b7c3-1757dcce01a1](https://docs.kics.io/latest/queries/kubernetes-queries/dab4ec72-ce2e-4732-b7c3-1757dcce01a1) | MEDIUM | Service Account Key File Not Properly Set | When using kube-apiserver command, the '--service-account-key-file' flag should be defined|[b7d0181d-0a9b-4611-9d1c-1ad4f0b620ff](https://docs.kics.io/latest/queries/kubernetes-queries/b7d0181d-0a9b-4611-9d1c-1ad4f0b620ff) | MEDIUM | Etcd Peer Client Certificate Authentication Set To False | When using etcd commands, the '--peer-client-cert-auth' flag should be set to true|[056ac60e-fe07-4acc-9b34-8e1d51716ab9](https://docs.kics.io/latest/queries/kubernetes-queries/056ac60e-fe07-4acc-9b34-8e1d51716ab9) | MEDIUM | ServiceAccount Allows Access Secrets | Roles and ClusterRoles when binded, should not use get, list or watch as verbs|[1c621b8e-2c6a-44f5-bd6a-fb0fb7ba33e2](https://docs.kics.io/latest/queries/kubernetes-queries/1c621b8e-2c6a-44f5-bd6a-fb0fb7ba33e2) | MEDIUM | Rotate Kubelet Server Certificate Not Active | The RotateKubeletServerCertificate argument should be true|[52d70f2e-3257-474c-b3dc-8ad9ba6a061a](https://docs.kics.io/latest/queries/kubernetes-queries/52d70f2e-3257-474c-b3dc-8ad9ba6a061a) | MEDIUM | Kubelet Client Periodic Certificate Switch Disabled | Kubelet argument --rotate-certificates should be true|[3f5ff8a7-5ad6-4d02-86f5-666307da1b20](https://docs.kics.io/latest/queries/kubernetes-queries/3f5ff8a7-5ad6-4d02-86f5-666307da1b20) | MEDIUM | Etcd Client Certificate File Not Defined | When using kube-apiserver commands, the '--etcd-cafile' flag should be defined|[c1032cf7-3628-44e2-bd53-38c17cf31b6b](https://docs.kics.io/latest/queries/kubernetes-queries/c1032cf7-3628-44e2-bd53-38c17cf31b6b) | MEDIUM | Shared Service Account | A Service Account token is shared between workloads|[cb7e695d-6a85-495c-b15f-23aed2519303](https://docs.kics.io/latest/queries/kubernetes-queries/cb7e695d-6a85-495c-b15f-23aed2519303) | MEDIUM | Not Unique Certificate Authority | Certificate Authority should be unique for etcd|[3d658f8b-d988-41a0-a841-40043121de1e](https://docs.kics.io/latest/queries/kubernetes-queries/3d658f8b-d988-41a0-a841-40043121de1e) | LOW | Secrets As Environment Variables | Container should not use secrets as environment variables|
テーブルのヘッダーは自分で作成する必要がありますが、ヘッダーのすぐ下に、先ほどのコマンドの結果をコピペすると、以下のような見た目になります。
ヘッダー
| id | severity | query name | description ||--|--|--|--|
完成したカテゴリーが Secret Management
である Kubernetes のクエリ一覧
id | severity | query name | description |
---|---|---|---|
ae8827e2-4af9-4baa-9998-87539ae0d6f0 | HIGH | Peer Auto TLS Set To True | When using etcd commands, the ‘—peer-auto-tls’ should be set to false |
98ce8b81-7707-4734-aa39-627c6db3d84b | HIGH | Auto TLS Set To True | When using etcd commands, the ‘—auto-tls’ should be set to false |
9391103a-d8d7-4671-ac5d-606ba7ccb0ac | MEDIUM | Etcd Client Certificate Authentication Set To False | When using etcd commands, the ‘—client-cert-auth’ flag should be defined |
36a27826-1bf5-49da-aeb0-a60a30c0e834 | MEDIUM | Kubelet Client Certificate Or Key Not Set | When using kube-apiserver command, the ‘kubelet-client-key’ and ‘kubelet-client-certificate’ flags should be set |
ec18a0d3-0069-4a58-a7fb-fbfe0b4bbbe0 | MEDIUM | Kubelet Certificate Authority Not Set | When using kube-apiserver command, the ‘kubelet-certificate-authority’ flag should be set |
dab4ec72-ce2e-4732-b7c3-1757dcce01a1 | MEDIUM | Service Account Key File Not Properly Set | When using kube-apiserver command, the ‘—service-account-key-file’ flag should be defined |
b7d0181d-0a9b-4611-9d1c-1ad4f0b620ff | MEDIUM | Etcd Peer Client Certificate Authentication Set To False | When using etcd commands, the ‘—peer-client-cert-auth’ flag should be set to true |
056ac60e-fe07-4acc-9b34-8e1d51716ab9 | MEDIUM | ServiceAccount Allows Access Secrets | Roles and ClusterRoles when binded, should not use get, list or watch as verbs |
1c621b8e-2c6a-44f5-bd6a-fb0fb7ba33e2 | MEDIUM | Rotate Kubelet Server Certificate Not Active | The RotateKubeletServerCertificate argument should be true |
52d70f2e-3257-474c-b3dc-8ad9ba6a061a | MEDIUM | Kubelet Client Periodic Certificate Switch Disabled | Kubelet argument —rotate-certificates should be true |
3f5ff8a7-5ad6-4d02-86f5-666307da1b20 | MEDIUM | Etcd Client Certificate File Not Defined | When using kube-apiserver commands, the ‘—etcd-cafile’ flag should be defined |
c1032cf7-3628-44e2-bd53-38c17cf31b6b | MEDIUM | Shared Service Account | A Service Account token is shared between workloads |
cb7e695d-6a85-495c-b15f-23aed2519303 | MEDIUM | Not Unique Certificate Authority | Certificate Authority should be unique for etcd |
3d658f8b-d988-41a0-a841-40043121de1e | LOW | Secrets As Environment Variables | Container should not use secrets as environment variables |
Kics 使い方
Kics の基本的な使い方
kics scan -p <DIRS>
で実行します。カンマ区切りで複数ディレクトリを指定できます。
$ helm create example$ docker run --rm -v $(pwd):/charts checkmarx/kics:latest scan -p /charts/example --no-progress
"kics scan" の出力結果
$ docker run --rm -v $(pwd):/charts checkmarx/kics:latest scan -p /charts --no-progress .0MO. OMMMx ;NMX; ... ... ....WMMMd cWMMM0. KMMMO ;xKWMMMMNOc. ,xXMMMMMWXkc.WMMMd .0MMMN: KMMMO :XMMMMMMMMMMMWl xMMMMMWMMMMMMlWMMMd lWMMMO. KMMMO xMMMMKc...'lXMk ,MMMMx .;dXxWMMMd.0MMMX; KMMMO cMMMMd ' 'MMMMNl'WMMMNWMMMMl KMMMO 0MMMN oMMMMMMMXkl.WMMMMMMMMMMo KMMMO 0MMMX .ckKWMMMMMM0.WMMMMWokMMMMk KMMMO oMMMMc . .:OMMMM0WMMMK. dMMMM0. KMMMO KMMMMx' ,kNc :WOc. .NMMMXWMMMd cWMMMX. KMMMO kMMMMMWXNMMMMMd .WMMMMWKO0NMMMMlWMMMd ,NMMMN, KMMMO 'xNMMMMMMMNx, .l0WMMMMMMMWk,xkkk: ,kkkkx okkkl ;xKXKx; ;dOKKkc
Scanning with Keeping Infrastructure as Code Secure v1.7.4
Files scanned: 4Parsed files: 3Queries loaded: 146Queries failed to execute: 0
------------------------------------
Root Container Not Mounted Read-only, Severity: LOW, Results: 1Description: Check if the root container filesystem is not being mounted read-only.Platform: KubernetesLearn more about this vulnerability: https://docs.kics.io/latest/queries/kubernetes-queries/a9c2f49d-0671-4fc9-9ece-f4e261e128d0
[1]: ../../charts/example/templates/deployment.yaml:1
Pod or Container Without ResourceQuota, Severity: LOW, Results: 1Description: Each namespace should have a ResourceQuota policy associated to limit the total amount of resources Pods, Containers and PersistentVolumeClaims can consumePlatform: KubernetesLearn more about this vulnerability: https://docs.kics.io/latest/queries/kubernetes-queries/48a5beba-e4c0-4584-a2aa-e6894e4cf424
[1]: ../../charts/example/templates/deployment.yaml:1
Pod or Container Without LimitRange, Severity: LOW, Results: 1Description: Each namespace should have a LimitRange policy associated to ensure that resource allocations of Pods, Containers and PersistentVolumeClaims do not exceed the defined boundariesPlatform: KubernetesLearn more about this vulnerability: https://docs.kics.io/latest/queries/kubernetes-queries/4a20ebac-1060-4c81-95d1-1f7f620e983b
[1]: ../../charts/example/templates/deployment.yaml:1
No Drop Capabilities for Containers, Severity: LOW, Results: 1Description: Sees if Kubernetes Drop Capabilities exists to ensure containers security contextPlatform: KubernetesLearn more about this vulnerability: https://docs.kics.io/latest/queries/kubernetes-queries/268ca686-7fb7-4ae9-b129-955a2a89064e
[1]: ../../charts/example/templates/deployment.yaml:1
Missing AppArmor Profile, Severity: LOW, Results: 1Description: Containers should be configured with an AppArmor profile to enforce fine-grained access control over low-level system resourcesPlatform: KubernetesLearn more about this vulnerability: https://docs.kics.io/latest/queries/kubernetes-queries/8b36775e-183d-4d46-b0f7-96a6f34a723f
[1]: ../../charts/example/templates/deployment.yaml:1
Image Without Digest, Severity: LOW, Results: 1Description: Images should be specified together with their digests to ensure integrityPlatform: KubernetesLearn more about this vulnerability: https://docs.kics.io/latest/queries/kubernetes-queries/7c81d34c-8e5a-402b-9798-9f442630e678
[1]: ../../charts/example/templates/deployment.yaml:1
Image Pull Policy Of The Container Is Not Set To Always, Severity: LOW, Results: 1Description: Image Pull Policy of the container must be defined and set to AlwaysPlatform: KubernetesLearn more about this vulnerability: https://docs.kics.io/latest/queries/kubernetes-queries/caa3479d-885d-4882-9aac-95e5e78ef5c2
[1]: ../../charts/example/templates/deployment.yaml:1
Using Unrecommended Namespace, Severity: MEDIUM, Results: 2Description: Namespaces like 'default', 'kube-system' or 'kube-public' should not be usedPlatform: KubernetesLearn more about this vulnerability: https://docs.kics.io/latest/queries/kubernetes-queries/611ab018-c4aa-4ba2-b0f6-a448337509a6
[1]: ../../charts/example/templates/serviceaccount.yaml:5
004: metadata: 005: name: {{ include "example.serviceAccountName" . }} 006: labels:
[2]: ../../charts/example/templates/deployment.yaml:1
Service Account Token Automount Not Disabled, Severity: MEDIUM, Results: 1Description: Service Account Tokens are automatically mounted even if not necessaryPlatform: KubernetesLearn more about this vulnerability: https://docs.kics.io/latest/queries/kubernetes-queries/48471392-d4d0-47c0-b135-cdec95eb3eef
[1]: ../../charts/example/templates/deployment.yaml:1
Seccomp Profile Is Not Configured, Severity: MEDIUM, Results: 1Description: Containers should be configured with a secure Seccomp profile to restrict potentially dangerous syscallsPlatform: KubernetesLearn more about this vulnerability: https://docs.kics.io/latest/queries/kubernetes-queries/f377b83e-bd07-4f48-a591-60c82b14a78b
[1]: ../../charts/example/templates/deployment.yaml:1
NET_RAW Capabilities Not Being Dropped, Severity: MEDIUM, Results: 1Description: Containers should drop 'ALL' or at least 'NET_RAW' capabilitiesPlatform: KubernetesLearn more about this vulnerability: https://docs.kics.io/latest/queries/kubernetes-queries/dbbc6705-d541-43b0-b166-dd4be8208b54
[1]: ../../charts/example/templates/deployment.yaml:1
Memory Requests Not Defined, Severity: MEDIUM, Results: 1Description: Memory requests should be defined for each container. This allows the kubelet to reserve the requested amount of system resources and prevents over-provisioning on individual nodesPlatform: KubernetesLearn more about this vulnerability: https://docs.kics.io/latest/queries/kubernetes-queries/229588ef-8fde-40c8-8756-f4f2b5825ded
[1]: ../../charts/example/templates/deployment.yaml:1
Memory Limits Not Defined, Severity: MEDIUM, Results: 1Description: Memory limits should be defined for each container. This prevents potential resource exhaustion by ensuring that containers consume not more than the designated amount of memoryPlatform: KubernetesLearn more about this vulnerability: https://docs.kics.io/latest/queries/kubernetes-queries/b14d1bc4-a208-45db-92f0-e21f8e2588e9
[1]: ../../charts/example/templates/deployment.yaml:1
Container Running With Low UID, Severity: MEDIUM, Results: 1Description: Check if containers are running with low UID, which might cause conflicts with the host's user table.Platform: KubernetesLearn more about this vulnerability: https://docs.kics.io/latest/queries/kubernetes-queries/02323c00-cdc3-4fdc-a310-4f2b3e7a1660
[1]: ../../charts/example/templates/deployment.yaml:32
031: - name: {{ .Chart.Name }} 032: securityContext: 033: {{- toYaml .Values.securityContext | nindent 12 }}
Container Running As Root, Severity: MEDIUM, Results: 1Description: Containers should only run as non-root user. This limits the exploitability of security misconfigurations and restricts an attacker's possibilities in case of compromisePlatform: KubernetesLearn more about this vulnerability: https://docs.kics.io/latest/queries/kubernetes-queries/cf34805e-3872-4c08-bf92-6ff7bb0cfadb
[1]: ../../charts/example/templates/deployment.yaml:1
CPU Requests Not Set, Severity: MEDIUM, Results: 1Description: CPU requests should be set to ensure the sum of the resource requests of the scheduled Containers is less than the capacity of the nodePlatform: KubernetesLearn more about this vulnerability: https://docs.kics.io/latest/queries/kubernetes-queries/ca469dd4-c736-448f-8ac1-30a642705e0a
[1]: ../../charts/example/templates/deployment.yaml:1
CPU Limits Not Set, Severity: MEDIUM, Results: 1Description: CPU limits should be set because if the system has CPU time free, a container is guaranteed to be allocated as much CPU as it requestsPlatform: KubernetesLearn more about this vulnerability: https://docs.kics.io/latest/queries/kubernetes-queries/4ac0e2b7-d2d2-4af7-8799-e8de6721ccda
[1]: ../../charts/example/templates/deployment.yaml:1
Privilege Escalation Allowed, Severity: HIGH, Results: 1Description: Containers should not run with allowPrivilegeEscalation in order to prevent them from gaining more privileges than their parent processPlatform: KubernetesLearn more about this vulnerability: https://docs.kics.io/latest/queries/kubernetes-queries/5572cc5e-1e4c-4113-92a6-7a8a3bd25e6d
[1]: ../../charts/example/templates/deployment.yaml:1
Results Summary:HIGH: 1MEDIUM: 11LOW: 7INFO: 0TOTAL: 19
Scan duration: 3.600578124s
特定のクエリのみ使用する
特定のクエリのみを使用したい場合は、-i, --include-queries strings
オプションを指定します。
カンマ区切りでクエリ ID を指定します。
$ docker run --rm -v $(pwd):/charts checkmarx/kics:latest scan -p /charts/example -i 5572cc5e-1e4c-4113-92a6-7a8a3bd25e6d,4ac0e2b7-d2d2-4af7-8799-e8de6721ccda --no-progress
seveiry: HIGH のクエリを使用する
--exclude-severities
を使用します。 オプションは exclude
と書いているので、この場合は HIGH 以外の info,low,medium
を指定します。
$ docker run --rm -v $(pwd):/charts checkmarx/kics:latest scan -p /charts/example --exclude-severities info,low,medium --no-progress
Kicsの出力形式を json にする
--report-formats strings
と -o, --output-path string
を使用します。
Kics は -o
オプションで指定したディレクトリ配下に results.json
を自動的に作成します。
コマンドの最後にある /charts
はコンテナ内のパスであることに注意
$ docker run --rm -v $(pwd):/charts checkmarx/kics:latest scan -p /charts/example --no-progress --report-formats json -o /charts
Checkov の概要と特徴
バージョン | |
---|---|
Checkov | 2.3.330 |
Checkov とポリシー
Checkov では、解析項目のことを”ポリシー”と呼びます。
bridgecrew.cloud を利用すると、API key を取得でき、CLI のオプションに設定できます。
Checkov は API key を利用しなくても解析はできます。
インストール方法
pip または homebrew を使ってインストールできます。
$ pip3 install checkov
$ brew install checkov
Installing Checkov - checkov.io
Checkov ができないこと
- API key を発行しないとポリシーのフィルターができない
Trivy では
--severiry HIGH
、 Kics では--excluder-severities info,low
オプションを使用することで解析項目をフィルタリングできます。
同じくCheckov にも-c, --check
オプションがありますが、このオプションを使用して severity を指定した項目のフィルタリングは API key を設定しないと使用できません。Terminal window $ checkov --framework helm -d example --skip-path test -c LOW[WARNI] Filtering checks by severity is only possible with an API key
Checkov の使い方
Checkov の基本的な使い方
ディレクトリを指定するときは -d <DIR>, --director <DIR>
を使用します。
$ helm create example$ checkov --framework helm -d example
特定のパス配下を解析しない —skip-path
--skip-path <ファイル名、ディレクトリ名>
たとえば、helm create
コマンドで作成したチャートにはデフォルトで tests
ディレクトリができます。
Checkov はこのディレクトリ配下の yaml も解析対象に入れてしまうため、コマンドを実行するときは対象外にしたいです。
$ tree example -L 2 -dexample├── charts└── templates └── tests
このとき --skip-path
を使用して、解析対象から外すことができます。
$ checkov --framework helm -d example --skip-path tests
--skip-path
は複数回指定できます。
以下は template/deployment.yaml
を解析対象から外した例です。
$ checkov --framework helm -d example --skip-path tests --skip-path deployment
失敗した項目のみ出力する —quiet
Checkov で解析を実行すると、コンソールに大量の結果を出力します。
$ checkov --framework helm -d example --skip-path tests | wc -l 1015
--quiet
オプションを設定すると、失敗した結果のみを出力できます。
$ checkov --framework helm -d example --skip-path tests --quiet | wc -l 710
ちなみに --compact
オプションを設定するとコードブロックを出力しなくなります。
--compact オプション
$ checkov --framework helm -d example --skip-path tests --quiet --compacthelm scan results:
Passed checks: 73, Failed checks: 15, Skipped checks: 0
Check: CKV_K8S_37: "Minimize the admission of containers with capabilities assigned" FAILED for resource: Deployment.default.release-name-example File: /example/templates/deployment.yaml:3-47 Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/kubernetes-policies/kubernetes-policy-index/bc-k8s-34.htmlCheck: CKV_K8S_31: "Ensure that the seccomp profile is set to docker/default or runtime/default" FAILED for resource: Deployment.default.release-name-example File: /example/templates/deployment.yaml:3-47 Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/kubernetes-policies/kubernetes-policy-index/bc-k8s-29.htmlCheck: CKV_K8S_20: "Containers should not run with allowPrivilegeEscalation" FAILED for resource: Deployment.default.release-name-example File: /example/templates/deployment.yaml:3-47 Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/kubernetes-policies/kubernetes-policy-index/bc-k8s-19.htmlCheck: CKV_K8S_15: "Image Pull Policy should be Always" FAILED for resource: Deployment.default.release-name-example File: /example/templates/deployment.yaml:3-47 Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/kubernetes-policies/kubernetes-policy-index/bc-k8s-14.htmlCheck: CKV_K8S_13: "Memory limits should be set" FAILED for resource: Deployment.default.release-name-example File: /example/templates/deployment.yaml:3-47 Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/kubernetes-policies/kubernetes-policy-index/bc-k8s-12.htmlCheck: CKV_K8S_40: "Containers should run as a high UID to avoid host conflict" FAILED for resource: Deployment.default.release-name-example File: /example/templates/deployment.yaml:3-47 Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/kubernetes-policies/kubernetes-policy-index/bc-k8s-37.htmlCheck: CKV_K8S_22: "Use read-only filesystem for containers where possible" FAILED for resource: Deployment.default.release-name-example File: /example/templates/deployment.yaml:3-47 Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/kubernetes-policies/kubernetes-policy-index/bc-k8s-21.htmlCheck: CKV_K8S_28: "Minimize the admission of containers with the NET_RAW capability" FAILED for resource: Deployment.default.release-name-example File: /example/templates/deployment.yaml:3-47 Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/kubernetes-policies/kubernetes-policy-index/bc-k8s-27.htmlCheck: CKV_K8S_38: "Ensure that Service Account Tokens are only mounted where necessary" FAILED for resource: Deployment.default.release-name-example File: /example/templates/deployment.yaml:3-47 Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/kubernetes-policies/kubernetes-policy-index/bc-k8s-35.htmlCheck: CKV_K8S_21: "The default namespace should not be used" FAILED for resource: Deployment.default.release-name-example File: /example/templates/deployment.yaml:3-47 Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/kubernetes-policies/kubernetes-policy-index/bc-k8s-20.htmlCheck: CKV_K8S_23: "Minimize the admission of root containers" FAILED for resource: Deployment.default.release-name-example File: /example/templates/deployment.yaml:3-47 Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/kubernetes-policies/kubernetes-policy-index/bc-k8s-22.htmlCheck: CKV_K8S_43: "Image should use digest" FAILED for resource: Deployment.default.release-name-example File: /example/templates/deployment.yaml:3-47 Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/kubernetes-policies/kubernetes-policy-index/bc-k8s-39.htmlCheck: CKV_K8S_11: "CPU limits should be set" FAILED for resource: Deployment.default.release-name-example File: /example/templates/deployment.yaml:3-47 Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/kubernetes-policies/kubernetes-policy-index/bc-k8s-10.htmlCheck: CKV_K8S_21: "The default namespace should not be used" FAILED for resource: Service.default.release-name-example File: /example/templates/service.yaml:3-22 Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/kubernetes-policies/kubernetes-policy-index/bc-k8s-20.htmlCheck: CKV_K8S_21: "The default namespace should not be used" FAILED for resource: ServiceAccount.default.release-name-example File: /example/templates/serviceaccount.yaml:3-12 Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/kubernetes-policies/kubernetes-policy-index/bc-k8s-20.html
Checkov のポリシーをフィルタリングする
Terraform や Dockerfile などは、Kics と同じようにコメントを書くことで解析の対象にしない方法があります。
Kubernetes のマニフェストでは annotations
に設定を追加することで、解析対象から外すことができます。
解析項目の CKV_K8S_21
は “デフォルトの namespace を使うな” という指摘です。
今回は Deployment のみ、解析に引っかからないようにします。
$ checkov --framework helm -d example --skip-path tests --quiet --compact | grep -A 3 CKV_K8S_21Check: CKV_K8S_21: "The default namespace should not be used" FAILED for resource: Deployment.default.release-name-example File: /example/templates/deployment.yaml:3-47 Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/kubernetes-policies/kubernetes-policy-index/bc-k8s-20.html--Check: CKV_K8S_21: "The default namespace should not be used" FAILED for resource: Service.default.release-name-example File: /example/templates/service.yaml:3-22 Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/kubernetes-policies/kubernetes-policy-index/bc-k8s-20.htmlCheck: CKV_K8S_21: "The default namespace should not be used" FAILED for resource: ServiceAccount.default.release-name-example File: /example/templates/serviceaccount.yaml:3-12 Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/kubernetes-policies/kubernetes-policy-index/bc-k8s-20.html
apiVersion: apps/v1kind: Deploymentmetadata: ...annotations: checkov.io/skip1: CKV_K8S_21=I don't care about default namespacespec: ...
意図した通り、Deployment リソースのみ指摘されなくなりました。
$ checkov --framework helm -d example --skip-path tests --quiet --compact | grep -A 3 CKV_K8S_21Check: CKV_K8S_21: "The default namespace should not be used" FAILED for resource: Service.default.release-name-example File: /example/templates/service.yaml:3-22 Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/kubernetes-policies/kubernetes-policy-index/bc-k8s-20.htmlCheck: CKV_K8S_21: "The default namespace should not be used" FAILED for resource: ServiceAccount.default.release-name-example File: /example/templates/serviceaccount.yaml:3-12 Guide: https://docs.paloaltonetworks.com/content/techdocs/en_US/prisma/prisma-cloud/prisma-cloud-code-security-policy-reference/kubernetes-policies/kubernetes-policy-index/bc-k8s-20.html
Suppressing/skipping - checkov.io
Checkov の出力形式を json にする
$ checkov --framework helm -d example -o json
Checkov のポリシー一覧を取得する
Trivy や Kics と違い Checkov は CLI でポリシーの一覧を取得できます。
一覧を取得するには、-l, --list
を指定します。
checkov -l
まとめ
静的解析ツールを触ってみた知ったを書いてみました。実際にツールを触ってみないと良し悪しはわからない、と感じました。
今回紹介した3つはローカル環境でも実施できるツールなので、まずは興味を持ったツールから使い始めることをオススメします。