github.com/khulnasoft-lab/defsec@v1.0.5-0.20230827010352-5e9f46893d95/internal/adapters/terraform/aws/ec2/vpc.go (about)

     1  package ec2
     2  
     3  import (
     4  	"github.com/khulnasoft-lab/defsec/pkg/providers/aws/ec2"
     5  	"github.com/khulnasoft-lab/defsec/pkg/terraform"
     6  	defsecTypes "github.com/khulnasoft-lab/defsec/pkg/types"
     7  )
     8  
     9  type naclAdapter struct {
    10  	naclRuleIDs terraform.ResourceIDResolutions
    11  }
    12  
    13  type sgAdapter struct {
    14  	sgRuleIDs terraform.ResourceIDResolutions
    15  }
    16  
    17  func adaptVPCs(modules terraform.Modules) []ec2.VPC {
    18  	var vpcs []ec2.VPC
    19  	for _, module := range modules {
    20  		for _, resource := range module.GetResourcesByType("aws_default_vpc") {
    21  			vpcs = append(vpcs, adaptVPC(modules, resource, true))
    22  		}
    23  		for _, resource := range module.GetResourcesByType("aws_vpc") {
    24  			vpcs = append(vpcs, adaptVPC(modules, resource, false))
    25  		}
    26  	}
    27  	return vpcs
    28  }
    29  
    30  func adaptVPC(modules terraform.Modules, block *terraform.Block, def bool) ec2.VPC {
    31  	var hasFlowLogs bool
    32  	for _, flow := range modules.GetResourcesByType("aws_flow_log") {
    33  		vpcAttr := flow.GetAttribute("vpc_id")
    34  		if vpcAttr.ReferencesBlock(block) {
    35  			hasFlowLogs = true
    36  			break
    37  		}
    38  	}
    39  	return ec2.VPC{
    40  		Metadata:        block.GetMetadata(),
    41  		ID:              defsecTypes.StringUnresolvable(block.GetMetadata()),
    42  		IsDefault:       defsecTypes.Bool(def, block.GetMetadata()),
    43  		SecurityGroups:  nil,
    44  		FlowLogsEnabled: defsecTypes.BoolDefault(hasFlowLogs, block.GetMetadata()),
    45  	}
    46  }
    47  
    48  func (a *sgAdapter) adaptSecurityGroups(modules terraform.Modules) []ec2.SecurityGroup {
    49  	var securityGroups []ec2.SecurityGroup
    50  	for _, resource := range modules.GetResourcesByType("aws_security_group") {
    51  		securityGroups = append(securityGroups, a.adaptSecurityGroup(resource, modules))
    52  	}
    53  	orphanResources := modules.GetResourceByIDs(a.sgRuleIDs.Orphans()...)
    54  	if len(orphanResources) > 0 {
    55  		orphanage := ec2.SecurityGroup{
    56  			Metadata:     defsecTypes.NewUnmanagedMetadata(),
    57  			Description:  defsecTypes.StringDefault("", defsecTypes.NewUnmanagedMetadata()),
    58  			IngressRules: nil,
    59  			EgressRules:  nil,
    60  			IsDefault:    defsecTypes.BoolUnresolvable(defsecTypes.NewUnmanagedMetadata()),
    61  			VPCID:        defsecTypes.StringUnresolvable(defsecTypes.NewUnmanagedMetadata()),
    62  		}
    63  		for _, sgRule := range orphanResources {
    64  			if sgRule.GetAttribute("type").Equals("ingress") {
    65  				orphanage.IngressRules = append(orphanage.IngressRules, adaptSGRule(sgRule, modules))
    66  			} else if sgRule.GetAttribute("type").Equals("egress") {
    67  				orphanage.EgressRules = append(orphanage.EgressRules, adaptSGRule(sgRule, modules))
    68  			}
    69  		}
    70  		securityGroups = append(securityGroups, orphanage)
    71  	}
    72  
    73  	return securityGroups
    74  }
    75  
    76  func (a *naclAdapter) adaptNetworkACLs(modules terraform.Modules) []ec2.NetworkACL {
    77  	var networkACLs []ec2.NetworkACL
    78  	for _, module := range modules {
    79  		for _, resource := range module.GetResourcesByType("aws_network_acl") {
    80  			networkACLs = append(networkACLs, a.adaptNetworkACL(resource, module))
    81  		}
    82  	}
    83  
    84  	orphanResources := modules.GetResourceByIDs(a.naclRuleIDs.Orphans()...)
    85  	if len(orphanResources) > 0 {
    86  		orphanage := ec2.NetworkACL{
    87  			Metadata:      defsecTypes.NewUnmanagedMetadata(),
    88  			Rules:         nil,
    89  			IsDefaultRule: defsecTypes.BoolDefault(false, defsecTypes.NewUnmanagedMetadata()),
    90  		}
    91  		for _, naclRule := range orphanResources {
    92  			orphanage.Rules = append(orphanage.Rules, adaptNetworkACLRule(naclRule))
    93  		}
    94  		networkACLs = append(networkACLs, orphanage)
    95  	}
    96  
    97  	return networkACLs
    98  }
    99  
   100  func (a *sgAdapter) adaptSecurityGroup(resource *terraform.Block, module terraform.Modules) ec2.SecurityGroup {
   101  	var ingressRules []ec2.SecurityGroupRule
   102  	var egressRules []ec2.SecurityGroupRule
   103  
   104  	descriptionAttr := resource.GetAttribute("description")
   105  	descriptionVal := descriptionAttr.AsStringValueOrDefault("Managed by Terraform", resource)
   106  
   107  	ingressBlocks := resource.GetBlocks("ingress")
   108  	for _, ingressBlock := range ingressBlocks {
   109  		ingressRules = append(ingressRules, adaptSGRule(ingressBlock, module))
   110  	}
   111  
   112  	egressBlocks := resource.GetBlocks("egress")
   113  	for _, egressBlock := range egressBlocks {
   114  		egressRules = append(egressRules, adaptSGRule(egressBlock, module))
   115  	}
   116  
   117  	rulesBlocks := module.GetReferencingResources(resource, "aws_security_group_rule", "security_group_id")
   118  	for _, ruleBlock := range rulesBlocks {
   119  		a.sgRuleIDs.Resolve(ruleBlock.ID())
   120  		if ruleBlock.GetAttribute("type").Equals("ingress") {
   121  			ingressRules = append(ingressRules, adaptSGRule(ruleBlock, module))
   122  		} else if ruleBlock.GetAttribute("type").Equals("egress") {
   123  			egressRules = append(egressRules, adaptSGRule(ruleBlock, module))
   124  		}
   125  	}
   126  
   127  	return ec2.SecurityGroup{
   128  		Metadata:     resource.GetMetadata(),
   129  		Description:  descriptionVal,
   130  		IngressRules: ingressRules,
   131  		EgressRules:  egressRules,
   132  		IsDefault:    defsecTypes.Bool(false, defsecTypes.NewUnmanagedMetadata()),
   133  		VPCID:        resource.GetAttribute("vpc_id").AsStringValueOrDefault("", resource),
   134  	}
   135  }
   136  
   137  func adaptSGRule(resource *terraform.Block, modules terraform.Modules) ec2.SecurityGroupRule {
   138  	ruleDescAttr := resource.GetAttribute("description")
   139  	ruleDescVal := ruleDescAttr.AsStringValueOrDefault("", resource)
   140  
   141  	var cidrs []defsecTypes.StringValue
   142  
   143  	cidrBlocks := resource.GetAttribute("cidr_blocks")
   144  	ipv6cidrBlocks := resource.GetAttribute("ipv6_cidr_blocks")
   145  	varBlocks := modules.GetBlocks().OfType("variable")
   146  
   147  	for _, vb := range varBlocks {
   148  		if cidrBlocks.IsNotNil() && cidrBlocks.ReferencesBlock(vb) {
   149  			cidrBlocks = vb.GetAttribute("default")
   150  		}
   151  		if ipv6cidrBlocks.IsNotNil() && ipv6cidrBlocks.ReferencesBlock(vb) {
   152  			ipv6cidrBlocks = vb.GetAttribute("default")
   153  		}
   154  	}
   155  
   156  	if cidrBlocks.IsNotNil() {
   157  		cidrs = cidrBlocks.AsStringValues()
   158  	}
   159  
   160  	if ipv6cidrBlocks.IsNotNil() {
   161  		cidrs = append(cidrs, ipv6cidrBlocks.AsStringValues()...)
   162  	}
   163  
   164  	return ec2.SecurityGroupRule{
   165  		Metadata:    resource.GetMetadata(),
   166  		Description: ruleDescVal,
   167  		CIDRs:       cidrs,
   168  	}
   169  }
   170  
   171  func (a *naclAdapter) adaptNetworkACL(resource *terraform.Block, module *terraform.Module) ec2.NetworkACL {
   172  	var networkRules []ec2.NetworkACLRule
   173  	rulesBlocks := module.GetReferencingResources(resource, "aws_network_acl_rule", "network_acl_id")
   174  	for _, ruleBlock := range rulesBlocks {
   175  		a.naclRuleIDs.Resolve(ruleBlock.ID())
   176  		networkRules = append(networkRules, adaptNetworkACLRule(ruleBlock))
   177  	}
   178  	return ec2.NetworkACL{
   179  		Metadata:      resource.GetMetadata(),
   180  		Rules:         networkRules,
   181  		IsDefaultRule: defsecTypes.BoolDefault(false, resource.GetMetadata()),
   182  	}
   183  }
   184  
   185  func adaptNetworkACLRule(resource *terraform.Block) ec2.NetworkACLRule {
   186  	var cidrs []defsecTypes.StringValue
   187  
   188  	typeVal := defsecTypes.StringDefault("ingress", resource.GetMetadata())
   189  
   190  	egressAtrr := resource.GetAttribute("egress")
   191  	if egressAtrr.IsTrue() {
   192  		typeVal = defsecTypes.String("egress", egressAtrr.GetMetadata())
   193  	} else if egressAtrr.IsNotNil() {
   194  		typeVal = defsecTypes.String("ingress", egressAtrr.GetMetadata())
   195  	}
   196  
   197  	actionAttr := resource.GetAttribute("rule_action")
   198  	actionVal := actionAttr.AsStringValueOrDefault("", resource)
   199  
   200  	protocolAtrr := resource.GetAttribute("protocol")
   201  	protocolVal := protocolAtrr.AsStringValueOrDefault("-1", resource)
   202  
   203  	cidrAttr := resource.GetAttribute("cidr_block")
   204  	if cidrAttr.IsNotNil() {
   205  		cidrs = append(cidrs, cidrAttr.AsStringValueOrDefault("", resource))
   206  	}
   207  	ipv4cidrAttr := resource.GetAttribute("ipv6_cidr_block")
   208  	if ipv4cidrAttr.IsNotNil() {
   209  		cidrs = append(cidrs, ipv4cidrAttr.AsStringValueOrDefault("", resource))
   210  	}
   211  
   212  	return ec2.NetworkACLRule{
   213  		Metadata: resource.GetMetadata(),
   214  		Type:     typeVal,
   215  		Action:   actionVal,
   216  		Protocol: protocolVal,
   217  		CIDRs:    cidrs,
   218  	}
   219  }