Repository: aquasecurity/tfsec (go)

Issue:
AWS ELBV2 Convert tfsec to use defsec

Pull request:
Switch elb to use defsec
resolves #1358 

Patch:
diff --git a/internal/app/tfsec/adapter/aws/elb/adapt.go b/internal/app/tfsec/adapter/aws/elb/adapt.go
index 64b4f5526..3be3b9751 100644
--- a/internal/app/tfsec/adapter/aws/elb/adapt.go
+++ b/internal/app/tfsec/adapter/aws/elb/adapt.go
@@ -21,6 +21,9 @@ func adaptLoadBalancers(modules []block.Module) []elb.LoadBalancer {
 		for _, resource := range module.GetResourcesByType("aws_alb") {
 			loadBalancers = append(loadBalancers, adaptLoadBalancer(resource, module))
 		}
+		for _, resource := range module.GetResourcesByType("aws_elb") {
+			loadBalancers = append(loadBalancers, adaptLoadBalancer(resource, module))
+		}
 	}
 	return loadBalancers
 }
diff --git a/internal/app/tfsec/rules/aws/elb/alb_not_public_rule.go b/internal/app/tfsec/rules/aws/elb/alb_not_public_rule.go
new file mode 100644
index 000000000..0427702e7
--- /dev/null
+++ b/internal/app/tfsec/rules/aws/elb/alb_not_public_rule.go
@@ -0,0 +1,29 @@
+package elb
+
+import (
+	"github.com/aquasecurity/defsec/rules/aws/elb"
+	"github.com/aquasecurity/tfsec/internal/app/tfsec/scanner"
+	"github.com/aquasecurity/tfsec/pkg/rule"
+)
+
+func init() {
+	scanner.RegisterCheckRule(rule.Rule{
+		LegacyID: "AWS005",
+		BadExample: []string{`
+ resource "aws_alb" "bad_example" {
+ 	internal = false
+ }
+ `},
+		GoodExample: []string{`
+ resource "aws_alb" "good_example" {
+ 	internal = true
+ }
+ `},
+		Links: []string{
+			"https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb",
+		},
+		RequiredTypes:  []string{"resource"},
+		RequiredLabels: []string{"aws_alb", "aws_elb", "aws_lb"},
+		Base:           elb.CheckAlbNotPublic,
+	})
+}
diff --git a/internal/app/tfsec/rules/aws/elb/http_not_used_rule.go b/internal/app/tfsec/rules/aws/elb/http_not_used_rule.go
new file mode 100644
index 000000000..0a629e301
--- /dev/null
+++ b/internal/app/tfsec/rules/aws/elb/http_not_used_rule.go
@@ -0,0 +1,29 @@
+package elb
+
+import (
+	"github.com/aquasecurity/defsec/rules/aws/elb"
+	"github.com/aquasecurity/tfsec/internal/app/tfsec/scanner"
+	"github.com/aquasecurity/tfsec/pkg/rule"
+)
+
+func init() {
+	scanner.RegisterCheckRule(rule.Rule{
+		LegacyID: "AWS004",
+		BadExample: []string{`
+ resource "aws_lb_listener" "bad_example" {
+ 	protocol = "HTTP"
+ }
+ `},
+		GoodExample: []string{`
+ resource "aws_lb_listener" "good_example" {
+ 	protocol = "HTTPS"
+ }
+ `},
+		Links: []string{
+			"https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener",
+		},
+		RequiredTypes:  []string{"resource"},
+		RequiredLabels: []string{"aws_lb_listener"},
+		Base:           elb.CheckHttpNotUsed,
+	})
+}
diff --git a/internal/app/tfsec/rules/aws/elbv2/alb_not_public_rule.go b/internal/app/tfsec/rules/aws/elbv2/alb_not_public_rule.go
deleted file mode 100644
index 46793fb4f..000000000
--- a/internal/app/tfsec/rules/aws/elbv2/alb_not_public_rule.go
+++ /dev/null
@@ -1,43 +0,0 @@
-package elbv2
-
-import (
-	"github.com/aquasecurity/defsec/rules"
-	"github.com/aquasecurity/defsec/rules/aws/elb"
-	"github.com/aquasecurity/tfsec/internal/app/tfsec/block"
-	"github.com/aquasecurity/tfsec/internal/app/tfsec/scanner"
-	"github.com/aquasecurity/tfsec/pkg/rule"
-	"github.com/zclconf/go-cty/cty"
-)
-
-func init() {
-	scanner.RegisterCheckRule(rule.Rule{
-		LegacyID: "AWS005",
-		BadExample: []string{`
- resource "aws_alb" "bad_example" {
- 	internal = false
- }
- `},
-		GoodExample: []string{`
- resource "aws_alb" "good_example" {
- 	internal = true
- }
- `},
-		Links: []string{
-			"https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb",
-		},
-		RequiredTypes:  []string{"resource"},
-		RequiredLabels: []string{"aws_alb", "aws_elb", "aws_lb"},
-		Base:           elb.CheckAlbNotPublic,
-		CheckTerraform: func(resourceBlock block.Block, _ block.Module) (results rules.Results) {
-			if resourceBlock.HasChild("load_balancer_type") && resourceBlock.GetAttribute("load_balancer_type").Equals("gateway") {
-				return
-			}
-			if internalAttr := resourceBlock.GetAttribute("internal"); internalAttr.IsNil() {
-				results.Add("Resource is exposed publicly.", resourceBlock)
-			} else if internalAttr.Type() == cty.Bool && internalAttr.Value().False() {
-				results.Add("Resource is exposed publicly.", internalAttr)
-			}
-			return results
-		},
-	})
-}
diff --git a/internal/app/tfsec/rules/aws/elbv2/http_not_used_rule.go b/internal/app/tfsec/rules/aws/elbv2/http_not_used_rule.go
deleted file mode 100644
index f733b43ed..000000000
--- a/internal/app/tfsec/rules/aws/elbv2/http_not_used_rule.go
+++ /dev/null
@@ -1,79 +0,0 @@
-package elbv2
-
-import (
-	"github.com/aquasecurity/defsec/rules"
-	"github.com/aquasecurity/defsec/rules/aws/elb"
-	"github.com/aquasecurity/tfsec/internal/app/tfsec/block"
-	"github.com/aquasecurity/tfsec/internal/app/tfsec/debug"
-	"github.com/aquasecurity/tfsec/internal/app/tfsec/scanner"
-	"github.com/aquasecurity/tfsec/pkg/rule"
-)
-
-func init() {
-	scanner.RegisterCheckRule(rule.Rule{
-		LegacyID: "AWS004",
-		BadExample: []string{`
- resource "aws_alb_listener" "bad_example" {
- 	protocol = "HTTP"
- }
- `},
-		GoodExample: []string{`
- resource "aws_alb_listener" "good_example" {
- 	protocol = "HTTPS"
- }
- `},
-		Links: []string{
-			"https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lb_listener",
-		},
-		RequiredTypes:  []string{"resource"},
-		RequiredLabels: []string{"aws_lb_listener", "aws_alb_listener"},
-		Base:           elb.CheckHttpNotUsed,
-		CheckTerraform: func(resourceBlock block.Block, module block.Module) (results rules.Results) {
-
-			if checkIfExempt(resourceBlock, module) {
-				return
-			}
-
-			protocolAttr := resourceBlock.GetAttribute("protocol")
-			if protocolAttr.IsNotNil() {
-				if protocolAttr.IsResolvable() && (protocolAttr.Equals("HTTPS", block.IgnoreCase) ||
-					protocolAttr.Equals("TLS", block.IgnoreCase)) {
-					return
-				}
-				if protocolAttr.IsResolvable() && protocolAttr.Equals("HTTP") {
-					// check if this is a redirect to HTTPS - if it is, then no problem
-					if redirectProtocolAttr := resourceBlock.GetNestedAttribute("default_action.redirect.protocol"); redirectProtocolAttr.IsNotNil() {
-						if redirectProtocolAttr.IsResolvable() && redirectProtocolAttr.Equals("HTTPS") {
-							return
-						}
-					}
-				}
-				results.Add("Resource uses plain HTTP instead of HTTPS.", protocolAttr)
-			} else {
-				results.Add("Resource uses plain HTTP instead of HTTPS.", resourceBlock)
-			}
-
-			return results
-		},
-	})
-}
-
-func checkIfExempt(resourceBlock block.Block, module block.Module) bool {
-	if resourceBlock.HasChild("load_balancer_arn") {
-		lbaAttr := resourceBlock.GetAttribute("load_balancer_arn")
-		if lbaAttr.IsResourceBlockReference("aws_lb") {
-			referencedBlock, err := module.GetReferencedBlock(lbaAttr, resourceBlock)
-			if err == nil {
-				if referencedBlock.HasChild("load_balancer_type") {
-					loadBalancerType := referencedBlock.GetAttribute("load_balancer_type")
-					if loadBalancerType.IsAny("gateway", "network") {
-						return true
-					}
-				}
-			} else {
-				debug.Log(err.Error())
-			}
-		}
-	}
-	return false
-}
diff --git a/internal/app/tfsec/rules/init.go b/internal/app/tfsec/rules/init.go
index abea154fc..591295ae5 100644
--- a/internal/app/tfsec/rules/init.go
+++ b/internal/app/tfsec/rules/init.go
@@ -20,7 +20,6 @@ import (
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/elasticache"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/elasticsearch"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/elb"
-	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/elbv2"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/iam"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/kinesis"
 	_ "github.com/aquasecurity/tfsec/internal/app/tfsec/rules/aws/kms"


Test patch:
diff --git a/internal/app/tfsec/rules/aws/elbv2/alb_not_public_rule_test.go b/internal/app/tfsec/rules/aws/elb/alb_not_public_rule_test.go
similarity index 99%
rename from internal/app/tfsec/rules/aws/elbv2/alb_not_public_rule_test.go
rename to internal/app/tfsec/rules/aws/elb/alb_not_public_rule_test.go
index ec138cbad..2d5c52e93 100644
--- a/internal/app/tfsec/rules/aws/elbv2/alb_not_public_rule_test.go
+++ b/internal/app/tfsec/rules/aws/elb/alb_not_public_rule_test.go
@@ -1,4 +1,4 @@
-package elbv2
+package elb
 
 import (
 	"testing"
diff --git a/internal/app/tfsec/rules/aws/elbv2/http_not_used_rule_test.go b/internal/app/tfsec/rules/aws/elb/http_not_used_rule_test.go
similarity index 88%
rename from internal/app/tfsec/rules/aws/elbv2/http_not_used_rule_test.go
rename to internal/app/tfsec/rules/aws/elb/http_not_used_rule_test.go
index 6bd6d71fa..c0cdc1f46 100644
--- a/internal/app/tfsec/rules/aws/elbv2/http_not_used_rule_test.go
+++ b/internal/app/tfsec/rules/aws/elb/http_not_used_rule_test.go
@@ -1,4 +1,4 @@
-package elbv2
+package elb
 
 import (
 	"testing"
@@ -18,7 +18,12 @@ func Test_AWSPlainHTTP(t *testing.T) {
 		{
 			name: "check aws_alb_listener using plain HTTP",
 			source: `
- resource "aws_alb_listener" "my-listener" {
+resource "aws_lb" "my-lb" {
+
+}
+
+ resource "aws_lb_listener" "my-listener" {
+	load_balancer_arn = aws_lb.my-lb.arn
  	protocol = "HTTP"
  }`,
 			mustIncludeResultCode: expectedCode,
@@ -26,7 +31,12 @@ func Test_AWSPlainHTTP(t *testing.T) {
 		{
 			name: "check aws_lb_listener using plain HTTP",
 			source: `
+resource "aws_lb" "my-lb" {
+
+}
+
  resource "aws_lb_listener" "my-listener" {
+	load_balancer_arn = aws_lb.my-lb.arn
  	protocol = "HTTP"
  }`,
 			mustIncludeResultCode: expectedCode,
@@ -34,7 +44,12 @@ func Test_AWSPlainHTTP(t *testing.T) {
 		{
 			name: "check aws_alb_listener using plain HTTP (via non specification)",
 			source: `
- resource "aws_alb_listener" "my-listener" {
+ resource "aws_lb" "my-lb" {
+
+}
+
+ resource "aws_lb_listener" "my-listener" {
+	load_balancer_arn = aws_lb.my-lb.arn
  }`,
 			mustIncludeResultCode: expectedCode,
 		},
@@ -42,7 +57,6 @@ func Test_AWSPlainHTTP(t *testing.T) {
 			name: "check aws_alb_listeneer should continue checks if the referenced if a load balancer is not gateway",
 			source: `
  resource "aws_lb" "gwlb" {
- 
  	load_balancer_type = "application"
  
  }