Snyk IaCでTerraformコードのセキュリティ解析をしてみた
こんにちは!AWS事業本部コンサルティング部のたかくに(@takakuni_)です。
今回は、Snyk IaCを使用してTerraformコードのセキュリティスキャンをしてみようと思います。
Snyk IaCとは
Snyk IaCとは、Snyk社が作成したIaCのセキュリティスキャンツールです。
Terraform, CloudFormation, ARMに対応しており、幅広いIaCツールのセキュリティスキャンが行える利点があります。
事前にルールセットが用意されており、迅速にコードの評価を行うことができます。また、自身でカスタムルールも定義可能なため柔軟な評価基準を設けることができます。
やってみた
Snyk IaCは、Snyk CLIまたはGUI(Web)でセキュリティスキャンを実行できます。
今回は、Snyk CLIを使用してTerraformのコードを解析したいと思います。使用するコードは以下になります。
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 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形式に変換します。
terraform plan -out=tfplan.binary
terraform show -json tfplan.binary > tf-plan.json
snyk iac test tf-plan.json
terraformのバイナリ形式やJSON形式の変換について、より詳しく知りたい方は以下のブログも重ねてご覧ください。
実行結果は以下の通りです。解析したいリソースにフォーカスできていることがわかります。
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
を行ってみました。
もう一度、以下のコマンドを使用して解析を行ってみます。
terraform plan -out=tfplan.binary
terraform show -json tfplan.binary > tf-plan.json
snyk iac test tf-plan.json
解析結果は以下の通りです。
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 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_)でした!