github.com/khulnasoft-lab/defsec@v1.0.5-0.20230827010352-5e9f46893d95/internal/adapters/terraform/google/compute/networks.go (about) 1 package compute 2 3 import ( 4 "strconv" 5 "strings" 6 7 defsecTypes "github.com/khulnasoft-lab/defsec/pkg/types" 8 9 "github.com/khulnasoft-lab/defsec/pkg/providers/google/compute" 10 "github.com/khulnasoft-lab/defsec/pkg/terraform" 11 ) 12 13 func adaptNetworks(modules terraform.Modules) (networks []compute.Network) { 14 15 networkMap := make(map[string]compute.Network) 16 17 for _, networkBlock := range modules.GetResourcesByType("google_compute_network") { 18 network := compute.Network{ 19 Metadata: networkBlock.GetMetadata(), 20 Firewall: nil, 21 Subnetworks: nil, 22 } 23 networkMap[networkBlock.ID()] = network 24 } 25 26 for _, subnetworkBlock := range modules.GetResourcesByType("google_compute_subnetwork") { 27 28 subnetwork := compute.SubNetwork{ 29 Metadata: subnetworkBlock.GetMetadata(), 30 Name: subnetworkBlock.GetAttribute("name").AsStringValueOrDefault("", subnetworkBlock), 31 EnableFlowLogs: defsecTypes.BoolDefault(false, subnetworkBlock.GetMetadata()), 32 } 33 34 // logging 35 if logConfigBlock := subnetworkBlock.GetBlock("log_config"); logConfigBlock.IsNotNil() { 36 subnetwork.EnableFlowLogs = defsecTypes.BoolExplicit(true, subnetworkBlock.GetBlock("log_config").GetMetadata()) 37 } 38 39 nwAttr := subnetworkBlock.GetAttribute("network") 40 if nwAttr.IsNotNil() { 41 if nwblock, err := modules.GetReferencedBlock(nwAttr, subnetworkBlock); err == nil { 42 if network, ok := networkMap[nwblock.ID()]; ok { 43 network.Subnetworks = append(network.Subnetworks, subnetwork) 44 networkMap[nwblock.ID()] = network 45 continue 46 } 47 } 48 } 49 50 placeholder := compute.Network{ 51 Metadata: defsecTypes.NewUnmanagedMetadata(), 52 Firewall: nil, 53 Subnetworks: nil, 54 } 55 placeholder.Subnetworks = append(placeholder.Subnetworks, subnetwork) 56 networks = append(networks, placeholder) 57 } 58 59 for _, firewallBlock := range modules.GetResourcesByType("google_compute_firewall") { 60 61 firewall := compute.Firewall{ 62 Metadata: firewallBlock.GetMetadata(), 63 Name: firewallBlock.GetAttribute("name").AsStringValueOrDefault("", firewallBlock), 64 IngressRules: nil, 65 EgressRules: nil, 66 SourceTags: firewallBlock.GetAttribute("source_tags").AsStringValueSliceOrEmpty(firewallBlock), 67 TargetTags: firewallBlock.GetAttribute("target_tags").AsStringValueSliceOrEmpty(firewallBlock), 68 } 69 70 for _, allowBlock := range firewallBlock.GetBlocks("allow") { 71 adaptFirewallRule(&firewall, firewallBlock, allowBlock, true) 72 } 73 for _, denyBlock := range firewallBlock.GetBlocks("deny") { 74 adaptFirewallRule(&firewall, firewallBlock, denyBlock, false) 75 } 76 77 nwAttr := firewallBlock.GetAttribute("network") 78 if nwAttr.IsNotNil() { 79 if nwblock, err := modules.GetReferencedBlock(nwAttr, firewallBlock); err == nil { 80 if network, ok := networkMap[nwblock.ID()]; ok { 81 network.Firewall = &firewall 82 networkMap[nwblock.ID()] = network 83 continue 84 } 85 } 86 } 87 88 placeholder := compute.Network{ 89 Metadata: defsecTypes.NewUnmanagedMetadata(), 90 Firewall: nil, 91 Subnetworks: nil, 92 } 93 placeholder.Firewall = &firewall 94 networks = append(networks, placeholder) 95 } 96 97 for _, nw := range networkMap { 98 networks = append(networks, nw) 99 } 100 101 return networks 102 } 103 104 func expandRange(ports string, attr *terraform.Attribute) []defsecTypes.IntValue { 105 ports = strings.ReplaceAll(ports, " ", "") 106 if !strings.Contains(ports, "-") { 107 i, err := strconv.Atoi(ports) 108 if err != nil { 109 return nil 110 } 111 return []defsecTypes.IntValue{ 112 defsecTypes.Int(i, attr.GetMetadata()), 113 } 114 } 115 parts := strings.Split(ports, "-") 116 if len(parts) != 2 { 117 return nil 118 } 119 start, err := strconv.Atoi(parts[0]) 120 if err != nil { 121 return nil 122 } 123 end, err := strconv.Atoi(parts[1]) 124 if err != nil { 125 return nil 126 } 127 var output []defsecTypes.IntValue 128 for i := start; i <= end; i++ { 129 output = append(output, defsecTypes.Int(i, attr.GetMetadata())) 130 } 131 return output 132 } 133 134 func adaptFirewallRule(firewall *compute.Firewall, firewallBlock, ruleBlock *terraform.Block, allow bool) { 135 protocolAttr := ruleBlock.GetAttribute("protocol") 136 portsAttr := ruleBlock.GetAttribute("ports") 137 138 var ports []defsecTypes.IntValue 139 rawPorts := portsAttr.AsStringValues() 140 for _, portStr := range rawPorts { 141 ports = append(ports, expandRange(portStr.Value(), portsAttr)...) 142 } 143 144 // ingress by default 145 isEgress := firewallBlock.GetAttribute("direction").Equals("EGRESS", terraform.IgnoreCase) 146 147 rule := compute.FirewallRule{ 148 Metadata: firewallBlock.GetMetadata(), 149 Enforced: defsecTypes.BoolDefault(true, firewallBlock.GetMetadata()), 150 IsAllow: defsecTypes.Bool(allow, ruleBlock.GetMetadata()), 151 Protocol: protocolAttr.AsStringValueOrDefault("tcp", ruleBlock), 152 Ports: ports, 153 } 154 155 disabledAttr := firewallBlock.GetAttribute("disabled") 156 switch { 157 case disabledAttr.IsNil(): 158 rule.Enforced = defsecTypes.BoolDefault(true, firewallBlock.GetMetadata()) 159 case disabledAttr.IsTrue(): 160 rule.Enforced = defsecTypes.Bool(false, disabledAttr.GetMetadata()) 161 default: 162 rule.Enforced = defsecTypes.Bool(true, disabledAttr.GetMetadata()) 163 } 164 165 if isEgress { 166 var destinations []defsecTypes.StringValue 167 if destinationAttr := firewallBlock.GetAttribute("destination_ranges"); destinationAttr.IsNotNil() { 168 destinations = append(destinations, destinationAttr.AsStringValues()...) 169 } 170 if len(destinations) == 0 { 171 destinations = append(destinations, defsecTypes.StringDefault("0.0.0.0/0", firewallBlock.GetMetadata())) 172 } 173 firewall.EgressRules = append(firewall.EgressRules, compute.EgressRule{ 174 Metadata: firewallBlock.GetMetadata(), 175 FirewallRule: rule, 176 DestinationRanges: destinations, 177 }) 178 } else { 179 var sources []defsecTypes.StringValue 180 if sourceAttr := firewallBlock.GetAttribute("source_ranges"); sourceAttr.IsNotNil() { 181 sources = append(sources, sourceAttr.AsStringValues()...) 182 } 183 if len(sources) == 0 { 184 sources = append(sources, defsecTypes.StringDefault("0.0.0.0/0", firewallBlock.GetMetadata())) 185 } 186 firewall.IngressRules = append(firewall.IngressRules, compute.IngressRule{ 187 Metadata: firewallBlock.GetMetadata(), 188 FirewallRule: rule, 189 SourceRanges: sources, 190 }) 191 } 192 193 }