terraform の静的セキュリティスキャンツールの比較 tfsec chekcov snyk terrascan
terraform の静的セキュリティスキャンツールの比較 tfsec chekcov snyk terrascan
私は普段AWS等のインフラの管理を行うときにはterraformを使ってその管理を行っています。
インフラを実装するにあたって、セキュリティのケアを行っていくことは大切であります[1]。
今回は、設計実装段階[2]にCLI[3]からセキュリティのチェックを行うことのできる静的セキュリティスキャンツールについていくつか比較してみました。
この記事が参考になる人は
- IaCをterraformでやっていてDevSecOpsをはじめてみようと思っている人
- tfsec,chekcov,snyk,terrascanのcliやgithub actionsへの導入方法を知りたい人
- tfsec,chekcov,snyk,terrascanの違いを知りたい人
対象のコード
下記の自作コードを今回のスキャン対象にしています。(TODO コンテナの例も入れ込みたい )
tfsec
tfsecはAqua Security社の、オープンソースツールです。
tfsecはTerraformコードのセキュリティチェックを行うツールで、公式のTerraformセキュリティガイドラインに従って、潜在的な脆弱性を検出します。
tfsecの導入
導入はbrewから行えます
$ brew install tfsec
tfsecの実行
前述の下記レポジトリに対して実行すると
下記のような結果に
Result #1 HIGH No public access block so not blocking public acls
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
s3.tf:1-3
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 resource "aws_s3_bucket" "main" {
2 name = "my-bucket-name"
3 }
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
ID aws-s3-block-public-acls
Impact PUT calls with public ACLs specified can make objects public
Resolution Enable blocking any PUT calls with a public ACL specified
More Information
- https://aquasecurity.github.io/tfsec/v1.28.1/checks/aws/s3/block-public-acls/
- https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block#block_public_acls
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Result #2 HIGH No public access block so not blocking public policies
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
s3.tf:1-3
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 resource "aws_s3_bucket" "main" {
2 name = "my-bucket-name"
3 }
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
ID aws-s3-block-public-policy
Impact Users could put a policy that allows public access
Resolution Prevent policies that allow public access being PUT
More Information
- https://aquasecurity.github.io/tfsec/v1.28.1/checks/aws/s3/block-public-policy/
- https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block#block_public_policy
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Result #3 HIGH Bucket does not have encryption enabled
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
s3.tf:1-3
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 resource "aws_s3_bucket" "main" {
2 name = "my-bucket-name"
3 }
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
ID aws-s3-enable-bucket-encryption
Impact The bucket objects could be read if compromised
Resolution Configure bucket encryption
More Information
- https://aquasecurity.github.io/tfsec/v1.28.1/checks/aws/s3/enable-bucket-encryption/
- https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket#enable-default-server-side-encryption
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
# ...省略
timings
──────────────────────────────────────────
disk i/o 10.536µs
parsing 114.543µs
adaptation 64.899µs
checks 5.613634ms
total 5.803612ms
counts
──────────────────────────────────────────
modules downloaded 0
modules processed 1
blocks processed 1
files read 1
results
──────────────────────────────────────────
passed 3
ignored 0
critical 0
high 6
medium 2
low 1
3 passed, 9 potential problem(s) detected.
結構ぞろぞろとでてきていますが
scan結果に下記のようなURLがあり
良いコード例と悪いコード例があり
それを参考に修正していくことになりそうです。
また、検出された問題について今回はわけあって対応しないみたいなときには
terraformのコード上に下記のようなコメントを書いておくと
# tfsec:ignore:aws-s3-specify-public-access-block
resource "aws_s3_bucket" "main" {
下記のようにtfsecの警告をignored
にすることはできます
$ tfsec --include-ignored
# ...省略
Result #9 IGNORED (LOW) Bucket does not have a corresponding public access block.
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
s3.tf:2-4
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
2 resource "aws_s3_bucket" "main" {
3 name = "my-bucket-name"
4 }
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
ID aws-s3-specify-public-access-block
Impact Public access policies may be applied to sensitive data buckets
Resolution Define a aws_s3_bucket_public_access_block for the given bucket to control public access policies
More Information
- https://aquasecurity.github.io/tfsec/v1.28.1/checks/aws/s3/specify-public-access-block/
- https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block#bucket
────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
timings
──────────────────────────────────────────
disk i/o 9.706µs
parsing 115.315µs
adaptation 65.411µs
checks 5.079941ms
total 5.270373ms
counts
──────────────────────────────────────────
modules downloaded 0
modules processed 1
blocks processed 1
files read 1
results
──────────────────────────────────────────
passed 3
ignored 1
critical 0
high 6
medium 2
low 0
3 passed, 1 ignored, 8 potential problem(s) detected.
ignored
したものをcheck結果に表示したい場合--include-ignored
オプションつきでtfsecを起動する必要がありました。
また、ignoreの有効期限を設定することもできて下記のように記述すれば可能です
# tfsec:ignore:aws-s3-specify-public-access-block:exp:2022-01-02
resource "aws_s3_bucket" "main" {
ignoreについてのドキュメントは下記です
tfsec GitHub Actions
GitHub Actionsへの追加は当該Github レポジトリのActions
タブからtfsec
を検索してconfitgure
ボタンを押すと、yamlの編集画面になります。
下記のように編集して追加すればtfsecをGitHub Actionsへ組み込むことができます
(私は、schedule実行のeventをコメント化しました)
checkcov
checkcovはBridgecrew社の、オープンソースツールです。
Terraformコードの静的分析を行い、セキュリティ、コスト、パフォーマンス、ベストプラクティスに関する問題を特定します。
checkcovの導入
導入はpipやhomebrew等から行えます。私はpython環境の整備はしていたのでpipでインストールしました
※python環境が必要です。私がubuntu22.04でのpython環境を構築した際の内容は下記で参照できます
$ pip install checkov
※もしhomebrewでinstallしたい場合は
$ brew install checkov
checkcovの実行
前述の下記レポジトリに対して実行すると
下記のような結果に
checkov --file s3.tf
[ terraform framework ]: 100%|████████████████████|[1/1], Current File Scanned=s
[ secrets framework ]: 100%|████████████████████|[1/1], Current File Scanned=s3.
_ _
___| |__ ___ ___| | _______ __
/ __| '_ \ / _ \/ __| |/ / _ \ \ / /
| (__| | | | __/ (__| < (_) \ V /
\___|_| |_|\___|\___|_|\_\___/ \_/
By bridgecrew.io | version: 2.3.124
terraform scan results:
Passed checks: 4, Failed checks: 7, Skipped checks: 0
# ...省略
Check: CKV_AWS_145: "Ensure that S3 buckets are encrypted with KMS by default"
FAILED for resource: aws_s3_bucket.main
File: /s3.tf:1-3
Guide: https://docs.bridgecrew.io/docs/ensure-that-s3-buckets-are-encrypted-with-kms-by-default
1 | resource "aws_s3_bucket" "main" {
2 | name = "my-bucket-name"
3 | }
tfsecの場合、passed
などの結果がコマンド実行結果の最終行にでてきていて、cliでの実行時は見やすいかもしれないと思いました。
checkovでもtfsec同様、scan結果に下記のようなURLがあり
それを参考に修正していくことになりそうです。
また、検出された問題について今回はわけあって対応しないみたいなときもcheckovでも
terraformのコード上に下記のようなコメントを書いておくと
resource "aws_s3_bucket" "main" {
# checkov:skip=CKV2_AWS_6
下記のようにcheckovのcheckをSKIPPED
することはできます
# ...省略
Passed checks: 4, Failed checks: 6, Skipped checks: 1
# ...省略
Check: CKV2_AWS_6: "Ensure that S3 bucket has a Public Access block"
SKIPPED for resource: aws_s3_bucket.main
Suppress comment: No comment provided
File: /s3.tf:2-5
Guide: https://docs.bridgecrew.io/docs/s3-bucket-should-have-public-access-blocks-defaults-to-false-if-the-public-access-block-is-not-attached
SKIPPED
されたものはCLIでの実行結果の最後に出力されます。
checkov GitHub Actions
checkov のgithub actionsは下記を参考にして
このような感じに導入できます
snyk
snykは、Terraformを含む多数のプログラミング言語やフレームワークに対応した、継続的なセキュリティ監視のための統合セキュリティプラットフォームです。Terraformに対応しており、Terraformのコードをスキャンし、潜在的なセキュリティ上の問題を特定することができます。
snykの導入
以下のcliを使います
導入はhomebrewから行えます。
$ brew tap snyk/tap
$ brew install snyk
node.jsの環境がすでにある場合は下記のようにinstallすることも可能です
$ npm install snyk@latest -g
snykの登録
snykを実行するためは登録が必要です
今回はpricingのstart free
からfree
planを登録してすすめています
登録を完了したあとcliで認証をします
$ snyk auth
snykの実行
前述の下記レポジトリに対して実行すると
下記のような結果に
$ snyk iac test
Snyk Infrastructure as Code
✔ Test completed.
Issues
Low Severity Issues: 3
[Low] S3 bucket versioning disabled
Info: S3 bucket versioning is disabled. Changes or deletion of objects will
not be reversible
Rule: https://snyk.io/security-rules/SNYK-CC-TF-124
Path: resource > aws_s3_bucket[main] > versioning > enabled
File: s3.tf
Resolve: For AWS provider < v4.0.0, set `versioning.enabled` attribute to
`true`. For AWS provider >= v4.0.0, add aws_s3_bucket_versioning
resource.
[Low] S3 bucket MFA delete control disabled
Info: S3 bucket will not enforce MFA login on delete requests. Object could
be deleted without stronger MFA authorization
Rule: https://snyk.io/security-rules/SNYK-CC-TF-127
Path: resource > aws_s3_bucket[main] > versioning > mfa_delete
File: s3.tf
Resolve: Follow instructions in `https://docs.aws.amazon.com/AmazonS3/latest/u
serguide/MultiFactorAuthenticationDelete.html` to manually configure
the MFA setting. For AWS provider < v4.0.0 set
`versioning.mfa_delete` attribute to `true` in aws_s3_bucket
resource. For AWS provider >= v4.0.0 set
'versioning_configuration.mfa_delete` attribute to `Enabled`. The
terraform change is required to reflect the setting in the state file
[Low] S3 server access logging is disabled
Info: The s3 access logs will not be collected. There will be no audit
trail of access to s3 objects
Rule: https://snyk.io/security-rules/SNYK-CC-TF-45
Path: input > resource > aws_s3_bucket[main] > logging
File: s3.tf
Resolve: For AWS provider < v4.0.0, add `logging` block attribute. For AWS
provider >= v4.0.0, add aws_s3_bucket_logging resource.
Medium Severity Issues: 1
[Medium] Non-encrypted S3 Bucket
Info: Non-encrypted S3 Bucket. A non-encrypted S3 bucket increases the
likelihood of unintentional data exposure
Rule: https://snyk.io/security-rules/SNYK-CC-TF-4
Path: input > resource > aws_s3_bucket[main]
File: s3.tf
Resolve: For AWS provider < v4.0.0, set `server_side_encryption_configuration`
block attribute. For AWS provider >= v4.0.0 add
aws_s3_bucket_server_side_encryption_configuration resource.
High Severity Issues: 1
[High] S3 block public ACLs control is disabled
Info: Bucket does not prevent creation of public ACLs. Anyone who can
manage bucket's ACLs will be able to grant public access to the
bucket
Rule: https://snyk.io/security-rules/SNYK-CC-TF-95
Path: resource > aws_s3_bucket[main]
File: s3.tf
Resolve: Set the `aws_s3_bucket_public_access_block` `block_public_acls` field
to true.
-------------------------------------------------------
Test Summary
Organization: piroz
Project name: piroz/try-iac-scanner
✔ Files without issues: 0
✗ Files with issues: 1
Ignored issues: 0
Total issues: 5 [ 0 critical, 1 high, 1 medium, 3 low ]
-------------------------------------------------------
Tip
New: Share your test results in the Snyk Web UI with the option --report
iacのscan以外にsnyk iac describe
で管理済みのリソースとのdrift
を検知するような機能もあるようで、snykは総合ツールの方向性で構築されていそうでした。
なお、snyk iac
については現状tf
ファイルをまたいで関連するリソース設定(例えばaws_s3_bucket_acl
とaws_s3_bucket
を別ファイルに定義)していた場合、誤検知してしまうような仕様になっているとのことで、tf
ファイルを分割しているような環境では注意が必要そうです。
snyk Github Actions
snykのtokenが必要なので下記の手順で取得します
cliは先の手順でセットアップ済みなのでsnyk config get api
で取得可能でした
todo
terrascan
terrascanもTerraformによって生成されたIaCコードをscanするツールでAWS,Azure,GCPに対応しています。
terrascanの導入
導入はhomebrewからも行えるのでhomebrewから導入しました。
$ brew install terrascan
terrascanの実行
前述の下記レポジトリに対して実行すると
下記のような結果に
$ terrascan scan
2023/04/16 08:39:24 [DEBUG] GET https://registry.terraform.io/v1/providers/hashicorp/aws/versions
Scan Errors -
IaC Type : arm
Directory : /home/xxx/try-iac-scanner
Error Message : ARM files not found in the directory /home/xxx/try-iac-scanner
-----------------------------------------------------------------------
IaC Type : docker
Directory : /home/xxx/try-iac-scanner
Error Message : Dockerfile not found in the directory /home/xxx/try-iac-scanner
-----------------------------------------------------------------------
IaC Type : cft
Directory : /home/xxx/try-iac-scanner/.github/workflows
Error Message : error while loading iac file '/home/xxx/try-iac-scanner/.github/workflows/checkov.yml', err: failed to find valid Resources key in file: /home/xxx/try-iac-scanner/.github/workflows/checkov.yml
-----------------------------------------------------------------------
IaC Type : cft
Directory : /home/xxx/try-iac-scanner/.github/workflows
Error Message : error while loading iac file '/home/xxx/try-iac-scanner/.github/workflows/snyk-infrastructure.yml', err: failed to find valid Resources key in file: /home/xxx/try-iac-scanner/.github/workflows/snyk-infrastructure.yml
-----------------------------------------------------------------------
IaC Type : cft
Directory : /home/xxx/try-iac-scanner/.github/workflows
Error Message : error while loading iac file '/home/xxx/try-iac-scanner/.github/workflows/tfsec.yml', err: failed to find valid Resources key in file: /home/xxx/try-iac-scanner/.github/workflows/tfsec.yml
-----------------------------------------------------------------------
IaC Type : kustomize
Directory : /home/xxx/try-iac-scanner
Error Message : kustomization.y(a)ml file not found in the directory /home/xxx/try-iac-scanner
-----------------------------------------------------------------------
IaC Type : helm
Directory : /home/xxx/try-iac-scanner
Error Message : no helm charts found in directory /home/xxx/try-iac-scanner
-----------------------------------------------------------------------
Scan Summary -
File/Folder : /home/xxx/try-iac-scanner
IaC Type : terraform
Scanned At : 2023-04-15 23:39:25.923043388 +0000 UTC
Policies Validated : 10
Violated Policies : 0
Low : 0
Medium : 0
High : 0
tfsec,checkov,snykが指摘していた問題についてはterrascanは指摘をしてくれなかったです。
Policies Validated: 10
な内容はどうだったか気になったので調べると
documentに記載の下記のpoliciesが調査されていそう?
terrascanが利用するregoのポリシーについては下記あたりにありそうだった
todo
Discussion