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 }