aquasecurity / trivy

Find vulnerabilities, misconfigurations, secrets, SBOM in containers, Kubernetes, code repositories, clouds and more
https://aquasecurity.github.io/trivy
Apache License 2.0
23.68k stars 2.33k forks source link

fix(terraform): false positive on "aws-s3-specify-public-access-block" #5001

Closed nikpivkin closed 1 year ago

nikpivkin commented 1 year ago

Source https://github.com/aquasecurity/tfsec/issues/1903

Describe the bug

When an existing bucket has the aws_s3_bucket_public_access_block applied from a module, then then tfsec reports problems when the bucket has a generated name.

To Reproduce

Run most recent tfsec, v1.28.0,

docker run --rm -it -v "$(pwd):/workspace" aquasec/tfsec:v1.28.0 /workspace

on following configuration:

resource "random_pet" "this" {
  length = 8
}

resource "aws_iam_role" "this" {
  name               = "role-name"
  assume_role_policy = jsonencode({})
}

# tfsec:ignore:aws-s3-enable-bucket-encryption
# tfsec:ignore:aws-s3-enable-bucket-logging
# tfsec:ignore:aws-s3-enable-versioning
# tfsec:ignore:aws-s3-encryption-customer-key
resource "aws_s3_bucket" "test_with_bucket_output" {
  ## These three cases return unexpected 5 findings for missing policy access block 
  bucket = aws_iam_role.this.name 
  # bucket = "prefix-${aws_iam_role.this.name}"
  # bucket  = random_pet.this.id

  ## These two cases return the expected 0 findings
  # bucket = "static"
  # bucket_prefix = "static"
}

module "apply_bucket_settings_with_bucket_output" {
  source = "./bucket-settings" 

  bucket = aws_s3_bucket.test_with_bucket_output.bucket
}

The source for the bucket-settings module:

variable "bucket" {
  type = string
}

resource "aws_s3_bucket_public_access_block" "this" {
  bucket                  = var.bucket
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

Expected behavior

No findings.

Output of your tfsec command with --debug flag

expand for debug details ```bash $ docker run --rm -it -v "$(pwd):/workspace" aquasec/tfsec:v1.28.0 /workspace --debug 44:09.948708274 system.info APP tfsec 44:09.948749534 system.info VERSION v1.28.0 44:09.948753659 system.info OS linux 44:09.948756895 system.info ARCH amd64 44:09.948762047 system.info KERNEL Linux version 3.10.0-957.27.2.el7.x86_64 (mockbuild@kbuilder.bsys.centos.org) (gcc version 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC) ) #1 SMP Mon Jul 29 17:46:05 UTC 2019 44:09.948767478 system.info TERM xterm 44:09.948770999 system.info SHELL 44:09.948774513 system.info GOVERSION go1.18.5 44:09.948778196 system.info GOROOT /opt/hostedtoolcache/go/1.18.5/x64 44:09.948782607 system.info CGO false 44:09.948786436 system.info CPUCOUNT 2 44:09.948789583 system.info MAXPROCS 2 44:09.948793210 system.info WORKDIR / 44:09.948798903 system.info UID 1000 44:09.948804377 system.info EUID 1000 44:09.948807587 system.info DOCKER true 44:09.948810657 system.info CI false 44:09.948813951 system.info HOSTNAME ead57ca502fb 44:09.948817189 system.info TEMP /tmp 44:09.948820378 system.info PATHSEP / 44:09.948823765 system.info CMD tfsec /workspace --debug 44:09.948832440 cmd Command args=[]string{"/workspace"} 44:09.948854815 cmd Determined path dir=/workspace 44:09.951999143 cmd Determined path root=/ 44:09.952016134 cmd Determined path rel=workspace 44:09.952138095 terraform.scanner Scanning [&{/ /}] at 'workspace'... 44:09.961508759 terraform.scanner.rego Loaded 4 embedded libraries. 44:10.033313097 terraform.scanner.rego Loaded 117 embedded policies. 44:10.250522989 terraform.scanner Scanning root module 'workspace'... 44:10.250561164 terraform.parser. Setting project/module root to 'workspace' 44:10.250565925 terraform.parser. Parsing FS from 'workspace' 44:10.256985264 terraform.parser. Parsing 'workspace/main.tf'... 44:10.262912800 terraform.parser. Added file workspace/main.tf. 44:10.262936720 terraform.parser. Evaluating module... 44:10.263235167 terraform.parser. Read 4 block(s) and 4 ignore(s) for module 'root' (1 file[s])... 44:10.263247583 terraform.parser. Added 0 variables from tfvars. 44:10.270737518 terraform.parser. Loaded module metadata for 2 module(s) from 'workspace/.terraform/modules/modules.json'. 44:10.270772071 terraform.parser. Working directory for module evaluation is '/' 44:10.270873211 terraform.parser..evaluator Filesystem key is 'f9088d3ed2db9899500f703a07bb505300c2b5cbc122ac4365ca04af35422e64' 44:10.270879055 terraform.parser..evaluator Starting module evaluation... 44:10.271171994 terraform.parser..evaluator Starting submodule evaluation... 44:10.271188821 terraform.parser..evaluator Module 'module.apply_bucket_settings_with_bucket_output' resolved to path 'workspace/bucket-settings' in filesystem '&{/ /}' using modules.json 44:10.271240677 terraform.parser. Parsing FS from 'workspace/bucket-settings' 44:10.272748226 terraform.parser. Parsing 'workspace/bucket-settings/main.tf'... 44:10.273525948 terraform.parser. Added file workspace/bucket-settings/main.tf. 44:10.273544214 terraform.parser..evaluator found module './bucket-settings' in .terraform/modules 44:10.273551894 terraform.parser..evaluator Loaded module 'apply_bucket_settings_with_bucket_output' from 'workspace/bucket-settings'. 44:10.273560040 terraform.parser. Evaluating module... 44:10.273719910 terraform.parser. Read 2 block(s) and 0 ignore(s) for module 'apply_bucket_settings_with_bucket_output' (1 file[s])... 44:10.273748828 terraform.parser. Added 3 input variables from module definition. 44:10.274416698 terraform.parser. Loaded module metadata for 2 module(s) from 'workspace/.terraform/modules/modules.json'. 44:10.274444552 terraform.parser. Working directory for module evaluation is '/' 44:10.274530030 terraform.parser..evaluator Filesystem key is 'f9088d3ed2db9899500f703a07bb505300c2b5cbc122ac4365ca04af35422e64' 44:10.274537409 terraform.parser..evaluator Starting module evaluation... 44:10.274686861 terraform.parser..evaluator Starting submodule evaluation... 44:10.274695800 terraform.parser..evaluator Finished processing 0 submodule(s). 44:10.274700950 terraform.parser..evaluator Starting post-submodule evaluation... 44:10.274825071 terraform.parser..evaluator Module evaluation complete. 44:10.274841127 terraform.parser. Finished parsing module 'apply_bucket_settings_with_bucket_output'. 44:10.274852547 terraform.parser..evaluator Finished processing 1 submodule(s). 44:10.274857971 terraform.parser..evaluator Starting post-submodule evaluation... 44:10.275402898 terraform.parser..evaluator Module evaluation complete. 44:10.275420187 terraform.parser. Finished parsing module 'root'. 44:10.275427619 terraform.executor Adapting modules... 44:10.275793495 terraform.executor Adapted 2 module(s) into defsec state data. 44:10.275803047 terraform.executor Using max routines of 1 44:10.275808827 terraform.executor Applying state modifier functions... 44:10.275962210 terraform.executor Initialised 388 rule(s). 44:10.275970255 terraform.executor Created pool with 1 worker(s) to apply rules. 44:10.277756754 terraform.scanner.rego Scanning 1 inputs... 44:10.459344336 terraform.executor Finished applying rules. 44:10.459367962 terraform.executor Applying ignores... 44:10.459416968 terraform.executor Ignored 'aws-s3-enable-bucket-encryption' at 'workspace/main.tf:15-24'. 44:10.459431361 terraform.executor Ignored 'aws-s3-enable-bucket-logging' at 'workspace/main.tf:15-24'. 44:10.459446010 terraform.executor Ignored 'aws-s3-enable-versioning' at 'workspace/main.tf:15-24'. 44:10.459455759 terraform.executor Ignored 'aws-s3-encryption-customer-key' at 'workspace/main.tf:15-24'. 44:10.459602114 cmd Exit code based on results: 1 Result #1 HIGH No public access block so not blocking public acls ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── main.tf:15-24 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 15 resource "aws_s3_bucket" "test_with_bucket_output" { 16 ## These three cases return an unexpected findings for missing policy access block 17 bucket = aws_iam_role.this.name # Fails for module applied settings 18 # bucket = "prefix-${aws_iam_role.this.name}" # Fails for module applied settings 19 # bucket = random_pet.this.id # Fails for module applied settings 20 21 ## These two cases return the expected 0 findings 22 # bucket = "static" # when the bucket name is hard-coded, then tfsec returns no problems 23 # bucket_prefix = "static" # when the bucket name is hard-coded, then tfsec returns no problems 24 } ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 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.0/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 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── main.tf:15-24 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 15 resource "aws_s3_bucket" "test_with_bucket_output" { 16 ## These three cases return an unexpected findings for missing policy access block 17 bucket = aws_iam_role.this.name # Fails for module applied settings 18 # bucket = "prefix-${aws_iam_role.this.name}" # Fails for module applied settings 19 # bucket = random_pet.this.id # Fails for module applied settings 20 21 ## These two cases return the expected 0 findings 22 # bucket = "static" # when the bucket name is hard-coded, then tfsec returns no problems 23 # bucket_prefix = "static" # when the bucket name is hard-coded, then tfsec returns no problems 24 } ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 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.0/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 No public access block so not ignoring public acls ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── main.tf:15-24 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 15 resource "aws_s3_bucket" "test_with_bucket_output" { 16 ## These three cases return an unexpected findings for missing policy access block 17 bucket = aws_iam_role.this.name # Fails for module applied settings 18 # bucket = "prefix-${aws_iam_role.this.name}" # Fails for module applied settings 19 # bucket = random_pet.this.id # Fails for module applied settings 20 21 ## These two cases return the expected 0 findings 22 # bucket = "static" # when the bucket name is hard-coded, then tfsec returns no problems 23 # bucket_prefix = "static" # when the bucket name is hard-coded, then tfsec returns no problems 24 } ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ID aws-s3-ignore-public-acls Impact PUT calls with public ACLs specified can make objects public Resolution Enable ignoring the application of public ACLs in PUT calls More Information - https://aquasecurity.github.io/tfsec/v1.28.0/checks/aws/s3/ignore-public-acls/ - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block#ignore_public_acls ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Result #4 HIGH No public access block so not restricting public buckets ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── main.tf:15-24 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 15 resource "aws_s3_bucket" "test_with_bucket_output" { 16 ## These three cases return an unexpected findings for missing policy access block 17 bucket = aws_iam_role.this.name # Fails for module applied settings 18 # bucket = "prefix-${aws_iam_role.this.name}" # Fails for module applied settings 19 # bucket = random_pet.this.id # Fails for module applied settings 20 21 ## These two cases return the expected 0 findings 22 # bucket = "static" # when the bucket name is hard-coded, then tfsec returns no problems 23 # bucket_prefix = "static" # when the bucket name is hard-coded, then tfsec returns no problems 24 } ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── ID aws-s3-no-public-buckets Impact Public buckets can be accessed by anyone Resolution Limit the access to public buckets to only the owner or AWS Services (eg; CloudFront) More Information - https://aquasecurity.github.io/tfsec/v1.28.0/checks/aws/s3/no-public-buckets/ - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block#restrict_public_buckets¡ ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── Result #5 LOW Bucket does not have a corresponding public access block. ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── main.tf:15-24 ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 15 resource "aws_s3_bucket" "test_with_bucket_output" { 16 ## These three cases return an unexpected findings for missing policy access block 17 bucket = aws_iam_role.this.name # Fails for module applied settings 18 # bucket = "prefix-${aws_iam_role.this.name}" # Fails for module applied settings 19 # bucket = random_pet.this.id # Fails for module applied settings 20 21 ## These two cases return the expected 0 findings 22 # bucket = "static" # when the bucket name is hard-coded, then tfsec returns no problems 23 # bucket_prefix = "static" # when the bucket name is hard-coded, then tfsec returns no problems 24 } ───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── 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.0/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 6.043775ms parsing 5.272172ms adaptation 359.184µs checks 183.525889ms total 195.20102ms counts ────────────────────────────────────────── modules downloaded 0 modules processed 2 blocks processed 6 files read 2 results ────────────────────────────────────────── passed 1 ignored 4 critical 0 high 4 medium 0 low 1 1 passed, 4 ignored, 5 potential problem(s) detected. ```

System Info

tfsec version: v1.28.0 terraform version: v1.2.9 OS: Alpine Linux v3.16

Example Code

see reproduction steps

Additional context

All 5 use cases above pass if the public access block is applied at the resource level next to the bucket

resource "aws_s3_bucket_public_access_block" "this" {
  bucket = aws_s3_bucket.test_with_bucket_output.bucket

  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}
simar7 commented 1 year ago

Closed via https://github.com/aquasecurity/defsec/pull/1475