Repository: aquasecurity/tfsec (go)

Issue:
For Each aws-s3-specify-public-access-block incorrectly failed
**Describe the bug**

aws-s3-specify-public-access-block shows erroneous violation if using with for_each blocks.

**To Reproduce**
Steps to reproduce the behavior:

```tf
resource "aws_s3_bucket" "example" {
  for_each      = toset(["example1", "example2"])
  bucket        = each.key
  .....
}

resource "aws_s3_bucket_public_access_block" "example" {
  for_each = aws_s3_bucket.example
  bucket   = each.value.id

  block_public_acls       = true
  block_public_policy     = true
}
```
This code will fail the rule listed, despite defining an aws_s3_bucket_public_access_block

**Expected behavior**
The rule should pass if aws_s3_bucket_public_access_block includes a for_each that references the bucket

**Info**

- OS: mac Big Sur (11.5)
- tfsec:
```shell
tfsec --version
0.55.1
```


Pull request description:
Reference checking now follows foreach
Resolves #994 

Patch:
diff --git a/internal/app/tfsec/block/reference.go b/internal/app/tfsec/block/reference.go
index 86e54222e..279ad04de 100644
--- a/internal/app/tfsec/block/reference.go
+++ b/internal/app/tfsec/block/reference.go
@@ -98,7 +98,7 @@ func (r *Reference) RefersTo(b Block) bool {
 	if r.NameLabel() != b.Reference().NameLabel() {
 		return false
 	}
-	if r.Key() != b.Reference().Key() {
+	if r.Key() != "" && r.Key() != b.Reference().Key() {
 		return false
 	}
 	return true
diff --git a/internal/app/tfsec/hclcontext/context.go b/internal/app/tfsec/hclcontext/context.go
index abdab8eb4..8c4b161e1 100644
--- a/internal/app/tfsec/hclcontext/context.go
+++ b/internal/app/tfsec/hclcontext/context.go
@@ -77,6 +77,15 @@ func (c *Context) getReferencingBlocks(originalBlock block.Block, referencingTyp
 		}
 		if attr.ReferencesBlock(originalBlock) {
 			results = append(results, block)
+		} else {
+			for _, ref := range attr.AllReferences() {
+				if ref.TypeLabel() == "each" {
+					fe := block.GetAttribute("for_each")
+					if fe.ReferencesBlock(originalBlock) {
+						results = append(results, block)
+					}
+				}
+			}
 		}
 	}
 	return results, nil


Test patch:
diff --git a/internal/app/tfsec/rules/aws/s3/specify_public_access_block_rule_test.go b/internal/app/tfsec/rules/aws/s3/specify_public_access_block_rule_test.go
index cdae13910..a0222d4ff 100644
--- a/internal/app/tfsec/rules/aws/s3/specify_public_access_block_rule_test.go
+++ b/internal/app/tfsec/rules/aws/s3/specify_public_access_block_rule_test.go
@@ -20,28 +20,46 @@ func Test_AWSS3BucketShouldHavePublicAccessBlock(t *testing.T) {
 			name: "Should fail when a bucket is missing the public access block",
 			source: `
 resource "aws_s3_bucket" "example" {
-  bucket = "example"
-  acl = "private-read"
+	bucket = "example"
+	acl = "private-read"
 }
-`,
+		`,
 			mustIncludeResultCode: expectedCode,
 		},
 		{
-			name: "Should pass when a bucket is not missing the public access block",
+			name: "Should fail when a bucket is missing the public access block (via foreach)",
 			source: `
 resource "aws_s3_bucket" "example" {
-  bucket = "example"
-  acl = "private-read"
+	for_each      = toset(["example1", "example2"])
+	bucket        = each.key
 }
-  
+	
 resource "aws_s3_bucket_public_access_block" "example" {
-  bucket = aws_s3_bucket.example.id
-  block_public_acls   = true
-  block_public_policy = true
+	for_each = aws_s3_bucket.example
+	bucket   = each.value.id
+	
+	block_public_acls       = true
+	block_public_policy     = true
 }
 `,
 			mustExcludeResultCode: expectedCode,
 		},
+		{
+			name: "Should pass when a bucket is not missing the public access block",
+			source: `
+resource "aws_s3_bucket" "example" {
+	bucket = "example"
+	acl = "private-read"
+}
+
+resource "aws_s3_bucket_public_access_block" "example" {
+	bucket = aws_s3_bucket.example.id
+	block_public_acls   = true
+	block_public_policy = true
+}
+		`,
+			mustExcludeResultCode: expectedCode,
+		},
 	}
 
 	for _, test := range tests {