Snyk IaCでTerraformコードのセキュリティ解析をしてみた

2022.07.15

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは!AWS事業本部コンサルティング部のたかくに(@takakuni_)です。

今回は、Snyk IaCを使用してTerraformコードのセキュリティスキャンをしてみようと思います。

Snyk IaCとは

Snyk IaCとは、Snyk社が作成したIaCのセキュリティスキャンツールです。

Terraform, CloudFormation, ARMに対応しており、幅広いIaCツールのセキュリティスキャンが行える利点があります。

事前にルールセットが用意されており、迅速にコードの評価を行うことができます。また、自身でカスタムルールも定義可能なため柔軟な評価基準を設けることができます。

やってみた

Snyk IaCは、Snyk CLIまたはGUI(Web)でセキュリティスキャンを実行できます。

今回は、Snyk CLIを使用してTerraformのコードを解析したいと思います。使用するコードは以下になります。

snyk_iac_test/main.tf

data "aws_availability_zones" "azs" {
  all_availability_zones = false
  state = "available"
}

module "vpc" {
  source = "terraform-aws-modules/vpc/aws"

  name = "my-vpc"
  cidr = "10.0.0.0/16"

  azs             = data.aws_availability_zones.azs.names
  private_subnets = ["10.0.1.0/24", "10.0.2.0/24", "10.0.3.0/24"]
  public_subnets  = ["10.0.101.0/24", "10.0.102.0/24", "10.0.103.0/24"]

  enable_nat_gateway = false
  enable_vpn_gateway = false

  tags = {}
}

resource "aws_s3_bucket" "bucket" {
  bucket = "snyk-test-bucket"
}

まずは、基本的のsnyk iac testコマンドを使用して解析を行います。実行結果は以下になります。

snyk_iac_test/

snyk iac test

Snyk Infrastructure as Code

- Snyk testing Infrastructure as Code configuration issues.
✔ Test completed.

Issues

Low Severity Issues: 7

  [Low] CloudWatch log group not encrypted with managed key
  Info:    Log group is not encrypted with customer managed key. Scope of use of the key cannot be controlled via KMS/IAM policies
  Rule:    https://snyk.io/security-rules/SNYK-CC-AWS-415
  Path:    resource > aws_cloudwatch_log_group[flow_log] > kms_key_id
  File:    .terraform/modules/vpc/examples/vpc-flow-logs/main.tf
  Resolve: Set `kms_key_id` attribute with customer managed key id

  [Low] CloudWatch Log group retention period not set
  Info:    Amazon CloudWatch log group does not specify retention period. Logs will be kept indefinitely and incur AWS costs
  Rule:    https://snyk.io/security-rules/SNYK-CC-TF-134
  Path:    resource > aws_cloudwatch_log_group[flow_log] > retention_in_days
  File:    .terraform/modules/vpc/examples/vpc-flow-logs/main.tf
  Resolve: Set `retention_in_days` attribute to required value, e.g. set `365`

  [Low] Default VPC resource detected
  Info:    Default VPC resources is being maintained. Default VPC is designed to help get started with AWS, however dedicated VPCs are recommended for any production deployments
  Rule:    https://snyk.io/security-rules/SNYK-CC-AWS-423
  Path:    resource > aws_default_vpc[this]
  File:    .terraform/modules/vpc/main.tf
  Resolve: Remove `aws_default_vpc` resource

  [Low] Public IPs are automatically mapped to instances
  Info:    Instances launched in this subnet will automatically have public IP assigned. Instances will be potentially accessible over public internet, which may lead to unauthorized access
  Rule:    https://snyk.io/security-rules/SNYK-CC-AWS-427
  Path:    resource > aws_subnet[public] > map_public_ip_on_launch
  File:    .terraform/modules/vpc/main.tf
  Resolve: Set `map_public_ip_on_launch` attribute  with value `true`

  [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[bucket] > versioning > enabled
  File:    main.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[bucket] > versioning > mfa_delete
  File:    main.tf
  Resolve: Follow instructions in `https://docs.aws.amazon.com/AmazonS3/latest/userguide/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[bucket] > logging
  File:    main.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: 2

  [Medium] IAM Policy grants full administrative rights
  Info:    The IAM Policy grants all permissions to all resources. Any identity with this policy will have full administrative rights in the account
  Rule:    https://snyk.io/security-rules/SNYK-CC-TF-119
  Path:    data > aws_iam_policy_document[generic_endpoint_policy]
  File:    .terraform/modules/vpc/examples/complete-vpc/main.tf
  Resolve: Set `Actions` and `Resources` attributes to limited subset, e.g `Actions: ['s3:Create*']`

  [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[bucket]
  File:    main.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] Wildcard action in IAM Policy
  Info:    The IAM policy allows all actions on resource. Granting permission to perform any action is against 'least privilege' principle
  Rule:    https://snyk.io/security-rules/SNYK-CC-TF-69
  Path:    data > aws_iam_policy_document[generic_endpoint_policy] > statement
  File:    .terraform/modules/vpc/examples/complete-vpc/main.tf
  Resolve: Set `statement.action` attribute to specific actions e.g. `s3:ListBucket`

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

Test Summary

  Organization: XXXXXXXXXXXXXXXXXXXXXXXXX
  Project name: XXXXXXXXXXX

✔ Files without issues: 38
✗ Files with issues: 4
  Ignored issues: 0
  Total issues: 10 [ 0 critical, 1 high, 2 medium, 7 low ]

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

Tip

  New: Share your test results in the Snyk Web UI with the option --report

上記の通り、snyk iac testコマンドはデフォルトで、実行するディレクトリ配下の全ての階層のコードを解析します。

そのため、今回検知されている[Low] CloudWatch log group not encrypted with managed keyの脆弱性は、今回作成するリソースとは関係ないですが、.terraform/modules/vpc/examples/vpc-flow-logs/main.tfで定義されているため検知されています。

作成されるリソースに対してコード解析を行う場合は、terraform planの結果に対して解析を行います。

解析にはひと工夫必要で、terraform planの「-out」オプションは、結果をバイナリ形式で出力します。ファイルを解析を行うため、terraform show -jsonでバイナリ形式からJSON形式に変換します。

snyk_iac_test/

terraform plan -out=tfplan.binary
terraform show -json tfplan.binary > tf-plan.json
snyk iac test tf-plan.json

terraformのバイナリ形式やJSON形式の変換について、より詳しく知りたい方は以下のブログも重ねてご覧ください。

実行結果は以下の通りです。解析したいリソースにフォーカスできていることがわかります。

snyk_iac_test/

snyk iac test tf-plan.json

Snyk Infrastructure as Code

- Snyk testing Infrastructure as Code configuration issues.
✔ Test completed.

Issues

Low Severity Issues: 6

  [Low] Public IPs are automatically mapped to instances
  Info:    Instances launched in this subnet will automatically have public IP assigned. Instances will be potentially accessible over public internet, which may lead to unauthorized access
  Rule:    https://snyk.io/security-rules/SNYK-CC-AWS-427
  Path:    resource > aws_subnet[public["2"]] > map_public_ip_on_launch
  File:    tf-plan.json
  Resolve: Set `map_public_ip_on_launch` attribute  with value `true`

  [Low] Public IPs are automatically mapped to instances
  Info:    Instances launched in this subnet will automatically have public IP assigned. Instances will be potentially accessible over public internet, which may lead to unauthorized access
  Rule:    https://snyk.io/security-rules/SNYK-CC-AWS-427
  Path:    resource > aws_subnet[public["0"]] > map_public_ip_on_launch
  File:    tf-plan.json
  Resolve: Set `map_public_ip_on_launch` attribute  with value `true`

  [Low] Public IPs are automatically mapped to instances
  Info:    Instances launched in this subnet will automatically have public IP assigned. Instances will be potentially accessible over public internet, which may lead to unauthorized access
  Rule:    https://snyk.io/security-rules/SNYK-CC-AWS-427
  Path:    resource > aws_subnet[public["1"]] > map_public_ip_on_launch
  File:    tf-plan.json
  Resolve: Set `map_public_ip_on_launch` attribute  with value `true`

  [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[bucket] > versioning > enabled
  File:    tf-plan.json
  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[bucket] > versioning > mfa_delete
  File:    tf-plan.json
  Resolve: Follow instructions in `https://docs.aws.amazon.com/AmazonS3/latest/userguide/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[bucket] > logging
  File:    tf-plan.json
  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[bucket]
  File:    tf-plan.json
  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.

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

Test Summary

  Organization: XXXXXXXXXXXXXXXXXXXXXXXXX
  Project name: XXXXXXXXXXX

✔ Files without issues: 0
✗ Files with issues: 1
  Ignored issues: 0
  Total issues: 7 [ 0 critical, 0 high, 1 medium, 6 low ]

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

Tip

  New: Share your test results in the Snyk Web UI with the option --report

terraform apply後の挙動

一旦、先ほどの脆弱性を是正せずterraform applyを行ってみました。

もう一度、以下のコマンドを使用して解析を行ってみます。

snyk_iac_test/

terraform plan -out=tfplan.binary
terraform show -json tfplan.binary > tf-plan.json
snyk iac test tf-plan.json

解析結果は以下の通りです。

snyk_iac_test/

snyk iac test tf-plan.json

Snyk Infrastructure as Code

- Snyk testing Infrastructure as Code configuration issues.
✔ Test completed.

Issues
  No vulnerable paths were found!

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

Test Summary

  Organization: XXXXXXXXXXXXXXXXXXXXXXXXX
  Project name: XXXXXXXXXXX

✔ Files without issues: 1
✗ Files with issues: 0
  Ignored issues: 0
  Total issues: 0 [ 0 critical, 0 high, 0 medium, 0 low ]

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

Tip

  New: Share your test results in the Snyk Web UI with the option --report

実は、Snyk IaCはデフォルトではterraform planの変更箇所について解析が行われる仕様です。

変更箇所に対して解析を行うため解析時間の短縮を大幅に見込める仕様となっています。CodeBuildで利用する場合は、利用時間に対して課金されるので嬉しいですね。

そのため、先ほど検知していた脆弱性は解析結果に出力されません。

既存でデプロイしたリソースも含めて解析を行う場合は、「--scan=planned-values」オプションを追加してコマンドを実行します。

snyk_iac_test/

snyk iac test tf-plan.json --scan=planned-values

Snyk Infrastructure as Code

- Snyk testing Infrastructure as Code configuration issues.
✔ Test completed.

Issues

Low Severity Issues: 6

  [Low] Public IPs are automatically mapped to instances
  Info:    Instances launched in this subnet will automatically have public IP assigned. Instances will be potentially accessible over public internet, which may lead to unauthorized access
  Rule:    https://snyk.io/security-rules/SNYK-CC-AWS-427
  Path:    resource > aws_subnet[public["2"]] > map_public_ip_on_launch
  File:    tf-plan.json
  Resolve: Set `map_public_ip_on_launch` attribute  with value `true`

  [Low] Public IPs are automatically mapped to instances
  Info:    Instances launched in this subnet will automatically have public IP assigned. Instances will be potentially accessible over public internet, which may lead to unauthorized access
  Rule:    https://snyk.io/security-rules/SNYK-CC-AWS-427
  Path:    resource > aws_subnet[public["0"]] > map_public_ip_on_launch
  File:    tf-plan.json
  Resolve: Set `map_public_ip_on_launch` attribute  with value `true`

  [Low] Public IPs are automatically mapped to instances
  Info:    Instances launched in this subnet will automatically have public IP assigned. Instances will be potentially accessible over public internet, which may lead to unauthorized access
  Rule:    https://snyk.io/security-rules/SNYK-CC-AWS-427
  Path:    resource > aws_subnet[public["1"]] > map_public_ip_on_launch
  File:    tf-plan.json
  Resolve: Set `map_public_ip_on_launch` attribute  with value `true`

  [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[bucket] > versioning > enabled
  File:    tf-plan.json
  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[bucket] > versioning > mfa_delete
  File:    tf-plan.json
  Resolve: Follow instructions in `https://docs.aws.amazon.com/AmazonS3/latest/userguide/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[bucket] > logging
  File:    tf-plan.json
  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[bucket]
  File:    tf-plan.json
  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.

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

Test Summary

  Organization: XXXXXXXXXXXXXXXXXXXXXXXXX
  Project name: XXXXXXXXXXX

✔ Files without issues: 0
✗ Files with issues: 1
  Ignored issues: 0
  Total issues: 7 [ 0 critical, 0 high, 1 medium, 6 low ]

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

Tip

  New: Share your test results in the Snyk Web UI with the option --report

参考

まとめ

以上、簡単ではありますがSnyk IaCを使用してTerraformコードのセキュリティスキャンしてみたでした。

Terraform, CloudFormation, ARMと幅広いIaCツールのセキュリティスキャンができる部分が大変魅力的です。

この記事がどなたかの参考になれば幸いです。

以上、AWS事業本部コンサルティング部のたかくに(@takakuni_)でした!