diff --git a/pkg/fanal/types/misconf.go b/pkg/fanal/types/misconf.go index 89e14359dee6..2f18d0b45592 100644 --- a/pkg/fanal/types/misconf.go +++ b/pkg/fanal/types/misconf.go @@ -31,12 +31,19 @@ type MisconfResult struct { type MisconfResults []MisconfResult type CauseMetadata struct { - Resource string `json:",omitempty"` - Provider string `json:",omitempty"` - Service string `json:",omitempty"` - StartLine int `json:",omitempty"` - EndLine int `json:",omitempty"` - Code Code `json:",omitempty"` + Resource string `json:",omitempty"` + Provider string `json:",omitempty"` + Service string `json:",omitempty"` + StartLine int `json:",omitempty"` + EndLine int `json:",omitempty"` + Code Code `json:",omitempty"` + Occurrences []Occurrence `json:",omitempty"` +} + +type Occurrence struct { + Resource string `json:",omitempty"` + Filename string `json:",omitempty"` + Location Location } type Code struct { diff --git a/pkg/misconf/scanner.go b/pkg/misconf/scanner.go index e60831b95f4a..3d638f1764f2 100644 --- a/pkg/misconf/scanner.go +++ b/pkg/misconf/scanner.go @@ -425,6 +425,16 @@ func NewCauseWithCode(underlying scan.Result) types.CauseMetadata { StartLine: flat.Location.StartLine, EndLine: flat.Location.EndLine, } + for _, o := range flat.Occurrences { + cause.Occurrences = append(cause.Occurrences, types.Occurrence{ + Resource: o.Resource, + Filename: o.Filename, + Location: types.Location{ + StartLine: o.StartLine, + EndLine: o.EndLine, + }, + }) + } if code, err := underlying.GetCode(); err == nil { cause.Code = types.Code{ Lines: lo.Map(code.Lines, func(l scan.Line, i int) types.Line { diff --git a/pkg/report/table/misconfig.go b/pkg/report/table/misconfig.go index 6a886c6ff965..b427c7357de4 100644 --- a/pkg/report/table/misconfig.go +++ b/pkg/report/table/misconfig.go @@ -163,6 +163,21 @@ func (r *misconfigRenderer) renderCode(misconf types.DetectedMisconfiguration) { } } r.printf(" %s%s\r\n", r.result.Target, lineInfo) + for i, occ := range misconf.CauseMetadata.Occurrences { + lineInfo := fmt.Sprintf("%d-%d", occ.Location.StartLine, occ.Location.EndLine) + if occ.Location.StartLine >= occ.Location.EndLine { + lineInfo = fmt.Sprintf("%d", occ.Location.StartLine) + } + + r.printf( + " %svia %s:%s (%s)\n", + strings.Repeat(" ", i+2), + occ.Filename, + lineInfo, + occ.Resource, + ) + } + r.printSingleDivider() for i, line := range lines { if line.Truncated { diff --git a/pkg/report/table/misconfig_test.go b/pkg/report/table/misconfig_test.go index 4a819e6a7c76..a57399f0e253 100644 --- a/pkg/report/table/misconfig_test.go +++ b/pkg/report/table/misconfig_test.go @@ -196,6 +196,145 @@ See https://google.com/search?q=bad%20config ──────────────────────────────────────── +`, + }, + { + name: "resource name in report", + input: types.Result{ + Target: "terraform-aws-modules/security-group/aws/main.tf", + Class: types.ClassConfig, + Type: "terraform", + MisconfSummary: &types.MisconfSummary{ + Successes: 5, + Failures: 1, + Exceptions: 0, + }, + Misconfigurations: []types.DetectedMisconfiguration{ + { + Type: "Terraform Security Check", + ID: "AVD-AWS-0107", + AVDID: "AVS-AWS-0107", + Title: "An ingress security group rule allows traffic from /0", + Description: "Opening up ports to the public internet is generally to be avoided. You should restrict access to IP addresses or ranges that explicitly require it where possible.", + Message: "Security group rule allows ingress from public internet.", + Query: "data..", + Resolution: "Set a more restrictive cidr range", + Severity: "CRITICAL", + PrimaryURL: "https://avd.aquasec.com/misconfig/avd-aws-0107", + References: []string{ + "https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/security-group-rules-reference.html", + "https://avd.aquasec.com/misconfig/avd-aws-0107", + }, + Status: "FAIL", + CauseMetadata: ftypes.CauseMetadata{ + Resource: "module.aws-security-groups[\"db1\"]", + Provider: "AWS", + Service: "ec2", + StartLine: 197, + EndLine: 204, + Code: ftypes.Code{ + Lines: []ftypes.Line{ + { + Number: 191, + Content: "resource \"aws_security_group_rule\" \"ingress_with_cidr_blocks\" {", + IsCause: false, + }, + { + Number: 192, + Truncated: true, + }, + { + Number: 197, + Truncated: true, + }, + { + Number: 198, + Content: " \",\",", + IsCause: true, + }, + { + Number: 199, + Content: " lookup(", + IsCause: true, + }, + { + Number: 200, + Content: " var.ingress_with_cidr_blocks[count.index],", + IsCause: true, + }, + { + Number: 201, + Content: " \"cidr_blocks\",", + IsCause: true, + }, + { + Number: 202, + Content: " join(\",\", var.ingress_cidr_blocks),", + IsCause: true, + }, + { + Number: 203, + Content: " ),", + IsCause: true, + LastCause: true, + }, + { + Number: 204, + Truncated: true, + }, + }, + }, + Occurrences: []ftypes.Occurrence{ + { + Resource: "aws_security_group_rule.ingress_with_cidr_blocks[0]", + Filename: "terraform-aws-modules/security-group/aws/main.tf", + Location: ftypes.Location{ + StartLine: 191, + EndLine: 227, + }, + }, + { + Resource: "module.aws-security-groups[\"db1\"]", + Filename: "sg.tf", + Location: ftypes.Location{ + StartLine: 1, + EndLine: 13, + }, + }, + }, + }, + }, + }, + }, + want: ` +terraform-aws-modules/security-group/aws/main.tf (terraform) +============================================================ +Tests: 6 (SUCCESSES: 5, FAILURES: 1, EXCEPTIONS: 0) +Failures: 1 (LOW: 0, MEDIUM: 0, HIGH: 0, CRITICAL: 1) + +CRITICAL: Security group rule allows ingress from public internet. +════════════════════════════════════════ +Opening up ports to the public internet is generally to be avoided. You should restrict access to IP addresses or ranges that explicitly require it where possible. + +See https://avd.aquasec.com/misconfig/avd-aws-0107 +──────────────────────────────────────── + terraform-aws-modules/security-group/aws/main.tf:197-204 + via terraform-aws-modules/security-group/aws/main.tf:191-227 (aws_security_group_rule.ingress_with_cidr_blocks[0]) + via sg.tf:1-13 (module.aws-security-groups["db1"]) +──────────────────────────────────────── + 191 resource "aws_security_group_rule" "ingress_with_cidr_blocks" { + ... + ... + 198 │ ",", + 199 │ lookup( + 200 │ var.ingress_with_cidr_blocks[count.index], + 201 │ "cidr_blocks", + 202 │ join(",", var.ingress_cidr_blocks), + 203 └ ), + ... +──────────────────────────────────────── + + `, }, } diff --git a/pkg/scanner/local/scan.go b/pkg/scanner/local/scan.go index cc093f01a757..472715ecc3cf 100644 --- a/pkg/scanner/local/scan.go +++ b/pkg/scanner/local/scan.go @@ -393,12 +393,13 @@ func toDetectedMisconfiguration(res ftypes.MisconfResult, defaultSeverity dbType Layer: layer, Traces: res.Traces, CauseMetadata: ftypes.CauseMetadata{ - Resource: res.Resource, - Provider: res.Provider, - Service: res.Service, - StartLine: res.StartLine, - EndLine: res.EndLine, - Code: res.Code, + Resource: res.Resource, + Provider: res.Provider, + Service: res.Service, + StartLine: res.StartLine, + EndLine: res.EndLine, + Code: res.Code, + Occurrences: res.Occurrences, }, } }