tfsec: bug: S3 bucket false positives when using variables

Describe the bug tfsec appears to flag S3 buckets as not having a corresponding aws_s3_bucket_public_access_block resource (and likely the other versioning, encryption, etc. resources) only when they’re derived from variables or a .tfvars file.

To Reproduce Consider the following contrived example to just test public access blocking:

variable "buckets" {
  type    = set(string)
  default = []
}

#tfsec:ignore:aws-s3-enable-bucket-encryption tfsec:ignore:aws-s3-enable-versioning tfsec:ignore:aws-s3-encryption-customer-key tfsec:ignore:aws-s3-enable-bucket-logging
resource "aws_s3_bucket" "buckets" {
  for_each = var.buckets
  bucket   = each.key
}

resource "aws_s3_bucket_public_access_block" "buckets" {
  for_each                = aws_s3_bucket.buckets
  bucket                  = each.value.id
  restrict_public_buckets = true
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
}

#tfsec:ignore:aws-s3-enable-bucket-encryption tfsec:ignore:aws-s3-enable-versioning tfsec:ignore:aws-s3-encryption-customer-key tfsec:ignore:aws-s3-enable-bucket-logging
resource "aws_s3_bucket" "bucket" {
  bucket = "baz"
}

resource "aws_s3_bucket_public_access_block" "bucket" {
  bucket                  = aws_s3_bucket.bucket.id
  restrict_public_buckets = true
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
}

and a terraform.tfvars file containing:

buckets = [
  "foo",
  "bar",
]

Expected behavior No problems detected anywhere, as all of the S3 buckets have a corresponding public access block resource.

Actual behavior If I run tfsec without a --tfvars-file:

$ tfsec --concise-output
WARNING: A tfvars file was found but not automatically used. Did you mean to specify the --tfvars-file flag?

No problems detected!

With the terraform.tfvars file:

$ tfsec --concise-output --tfvars-file terraform.tfvars 

Results #1-2 HIGH No public access block so not blocking public acls (2 similar results)
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  main.tf:7-10
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  Individual Causes
  - main.tf:7-10 (aws_s3_bucket.buckets["bar"])
  - main.tf:7-10 (aws_s3_bucket.buckets["foo"])
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
          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.26.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
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────


Results #3-4 HIGH No public access block so not blocking public policies (2 similar results)
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  main.tf:7-10
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  Individual Causes
  - main.tf:7-10 (aws_s3_bucket.buckets["foo"])
  - main.tf:7-10 (aws_s3_bucket.buckets["bar"])
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
          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.26.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
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────


Results #5-6 HIGH No public access block so not ignoring public acls (2 similar results)
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  main.tf:7-10
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  Individual Causes
  - main.tf:7-10 (aws_s3_bucket.buckets["foo"])
  - main.tf:7-10 (aws_s3_bucket.buckets["bar"])
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
          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.26.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
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────


Results #7-8 HIGH No public access block so not restricting public buckets (2 similar results)
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  main.tf:7-10
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  Individual Causes
  - main.tf:7-10 (aws_s3_bucket.buckets["bar"])
  - main.tf:7-10 (aws_s3_bucket.buckets["foo"])
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
          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.26.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¡
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────


Results #9-10 LOW Bucket does not have a corresponding public access block. (2 similar results)
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  main.tf:7-10
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
  Individual Causes
  - main.tf:7-10 (aws_s3_bucket.buckets["foo"])
  - main.tf:7-10 (aws_s3_bucket.buckets["bar"])
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
          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.26.0/checks/aws/s3/specify-public-access-block/
  - https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block#bucket
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────


  8 passed, 12 ignored, 10 potential problem(s) detected.

It’s only flagging the two S3 buckets that are derived from the terraform.tfvars file.

Output of your tfsec command with --debug flag

39:40.999548800 system.info                      APP       tfsec
39:40.999581200 system.info                      VERSION   v1.26.0
39:40.999585200 system.info                      OS        linux
39:40.999601700 system.info                      ARCH      amd64
39:40.999606200 system.info                      KERNEL    Linux version 5.10.102.1-microsoft-standard-WSL2 (oe-user@oe-host) (x86_64-msft-linux-gcc (GCC) 9.3.0, GNU ld (GNU Binutils) 2.34.0.20200220) #1 SMP Wed Mar 2 00:30:59 UTC 2022
39:40.999625300 system.info                      TERM      xterm-256color
39:40.999642800 system.info                      SHELL     /bin/ash
39:40.999659500 system.info                      GOVERSION go1.18.3
39:40.999664700 system.info                      GOROOT    /opt/hostedtoolcache/go/1.18.3/x64
39:40.999680300 system.info                      CGO       false
39:40.999697200 system.info                      CPUCOUNT  8
39:40.999714000 system.info                      MAXPROCS  8
39:40.999730600 system.info                      WORKDIR   /test
39:40.999747500 system.info                      UID       0
39:40.999764300 system.info                      EUID      0
39:40.999780800 system.info                      DOCKER    true
39:40.999797400 system.info                      CI        false
39:40.999814100 system.info                      HOSTNAME  beb8e95fb341
39:40.999818100 system.info                      TEMP      /tmp
39:40.999835700 system.info                      PATHSEP   /
39:40.999840000 system.info                      CMD       tfsec --concise-output --tfvars-file terraform.tfvars --debug
39:40.999847900 cmd                              Command args=[]string{}
39:41.000209900 cmd                              Determined path dir=/test
39:41.000233400 cmd                              Determined path root=/
39:41.000252300 cmd                              Determined path rel=test
39:41.001007100 terraform.scanner                Scanning [&{/ /}] at 'test'...
39:41.003882600 terraform.scanner.rego           Loaded 4 embedded libraries.
39:41.037419500 terraform.scanner.rego           Loaded 72 embedded policies.
39:41.104719400 terraform.scanner                Scanning root module 'test'...
39:41.104784600 terraform.parser.<root>          Setting project/module root to 'test'
39:41.104790000 terraform.parser.<root>          Parsing FS from 'test'
39:41.107116200 terraform.parser.<root>          Parsing 'test/main.tf'...
39:41.119514800 terraform.parser.<root>          Added file test/main.tf.
39:41.120178100 terraform.parser.<root>          Evaluating module...
39:41.120512200 terraform.parser.<root>          Read 5 block(s) and 8 ignore(s) for module 'root' (1 file[s])...
39:41.123008000 terraform.parser.<root>          Added 1 variables from tfvars.
39:41.123416600 terraform.parser.<root>          Error loading module metadata: open //test/.terraform/modules/modules.json: no such file or directory.
39:41.124051000 terraform.parser.<root>          Working directory for module evaluation is '/test'
39:41.124195700 terraform.parser.<root>.evaluator Filesystem key is 'f9088d3ed2db9899500f703a07bb505300c2b5cbc122ac4365ca04af35422e64'
39:41.124229300 terraform.parser.<root>.evaluator Starting module evaluation...
39:41.124638900 terraform.parser.<root>.evaluator Expanded block 'aws_s3_bucket.buckets' into 2 clones via 'for_each' attribute.
39:41.124832600 terraform.parser.<root>.evaluator Expanded block 'aws_s3_bucket_public_access_block.buckets' into 2 clones via 'for_each' attribute.
39:41.124890900 terraform.parser.<root>.evaluator Starting submodule evaluation...
39:41.124900500 terraform.parser.<root>.evaluator Finished processing 0 submodule(s).
39:41.124927600 terraform.parser.<root>.evaluator Starting post-submodule evaluation...
39:41.125177000 terraform.parser.<root>.evaluator Module evaluation complete.
39:41.125220700 terraform.parser.<root>          Finished parsing module 'root'.
39:41.125250200 terraform.executor               Adapting modules...
39:41.135657200 terraform.executor               Adapted 1 module(s) into defsec state data.
39:41.135693500 terraform.executor               Using max routines of 7
39:41.135713400 terraform.executor               Applying state modifier functions...
39:41.135732100 terraform.executor               Initialised 335 rule(s).
39:41.135748700 terraform.executor               Created pool with 7 worker(s) to apply rules.
39:41.184897900 terraform.scanner.rego           Scanning 1 inputs...
39:41.205681200 terraform.executor               Finished applying rules.
39:41.205725100 terraform.executor               Applying ignores...
39:41.207459400 terraform.executor               Ignored 'aws-s3-enable-bucket-encryption' at 'test/main.tf:22-24'.
39:41.207507900 terraform.executor               Ignored 'aws-s3-enable-bucket-encryption' at 'test/main.tf:7-10'.
39:41.207541400 terraform.executor               Ignored 'aws-s3-enable-bucket-encryption' at 'test/main.tf:7-10'.
39:41.207552800 terraform.executor               Ignored 'aws-s3-enable-bucket-logging' at 'test/main.tf:22-24'.
39:41.207576900 terraform.executor               Ignored 'aws-s3-enable-bucket-logging' at 'test/main.tf:7-10'.
39:41.207603100 terraform.executor               Ignored 'aws-s3-enable-bucket-logging' at 'test/main.tf:7-10'.
39:41.207612200 terraform.executor               Ignored 'aws-s3-enable-versioning' at 'test/main.tf:22-24'.
39:41.207645900 terraform.executor               Ignored 'aws-s3-enable-versioning' at 'test/main.tf:7-10'.
39:41.207671700 terraform.executor               Ignored 'aws-s3-enable-versioning' at 'test/main.tf:7-10'.
39:41.207687400 terraform.executor               Ignored 'aws-s3-encryption-customer-key' at 'test/main.tf:22-24'.
39:41.207691700 terraform.executor               Ignored 'aws-s3-encryption-customer-key' at 'test/main.tf:7-10'.
39:41.207695900 terraform.executor               Ignored 'aws-s3-encryption-customer-key' at 'test/main.tf:7-10'.
39:41.208034800 cmd                              Exit code based on results: 1

System Info

  • tfsec version: v1.26.0
  • terraform version: 1.1.9
  • OS: Linux

Example Code See above.

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 3
  • Comments: 15 (2 by maintainers)

Most upvoted comments

Taken a look at this and it works when the var is used directly, it appears that we’re not supporting using a resource as a foreach source.

That is to say;

resource "aws_s3_bucket" "buckets" {
  for_each = var.buckets
  bucket   = each.value
}

resource "aws_s3_bucket_public_access_block" "buckets" {
  for_each                = var.buckets           
  bucket                  = each.value
  restrict_public_buckets = true
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
}

this works. I’ll look at fixing this early next week

It seems to have specifically fixed the aws_s3_bucket_public_access_block block, but it still breaks for aws_s3_bucket_server_side_encryption_configuration, aws_s3_bucket_logging, and aws_s3_bucket_versioning.

Hey, 1.26.2 was just released and I believe it fixes this issue (as it fixed mine; it was the code expecting a bucket name, and only a bucket name, instead of also the ID, as required by the AWS API specs)