Skip to content

Commit

Permalink
Merge branch 'master' into nik-pseudo-p
Browse files Browse the repository at this point in the history
  • Loading branch information
simar7 authored Jul 20, 2023
2 parents b28e7a1 + 193ef12 commit b31ab1c
Show file tree
Hide file tree
Showing 5 changed files with 168 additions and 3 deletions.
2 changes: 2 additions & 0 deletions pkg/scan/flat.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type FlatResult struct {
Warning bool `json:"warning"`
Status Status `json:"status"`
Resource string `json:"resource"`
Occurrences []Occurrence `json:"occurrences,omitempty"`
Location FlatRange `json:"location"`
}

Expand Down Expand Up @@ -60,6 +61,7 @@ func (r *Result) Flatten() FlatResult {
Severity: r.rule.Severity,
Status: r.status,
Resource: resMetadata.Reference(),
Occurrences: r.Occurrences(),
Warning: r.IsWarning(),
Location: FlatRange{
Filename: rng.GetFilename(),
Expand Down
28 changes: 28 additions & 0 deletions pkg/scan/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,3 +336,31 @@ func rawToString(raw interface{}) string {
return "?"
}
}

type Occurrence struct {
Resource string `json:"resource"`
Filename string `json:"filename"`
StartLine int `json:"start_line"`
EndLine int `json:"end_line"`
}

func (r *Result) Occurrences() []Occurrence {
var occurrences []Occurrence

mod := &r.metadata

for {
mod = mod.Parent()
if mod == nil {
break
}
parentRange := mod.Range()
occurrences = append(occurrences, Occurrence{
Resource: mod.Reference(),
Filename: parentRange.GetFilename(),
StartLine: parentRange.GetStartLine(),
EndLine: parentRange.GetEndLine(),
})
}
return occurrences
}
56 changes: 56 additions & 0 deletions pkg/scan/result_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package scan_test

import (
"testing"

"github.com/aquasecurity/defsec/pkg/scan"
"github.com/aquasecurity/defsec/pkg/types"
"github.com/stretchr/testify/assert"
)

func Test_Occurrences(t *testing.T) {
tests := []struct {
name string
factory func() *scan.Result
expected []scan.Occurrence
}{
{
name: "happy",
factory: func() *scan.Result {
r := scan.Result{}
causeResourceMeta := types.NewMetadata(types.NewRange(
"main.tf", 1, 13, "", nil,
), "module.aws-security-groups[\"db1\"]")

parentMeta := types.NewMetadata(types.NewRange(
"terraform-aws-modules/security-group/aws/main.tf", 191, 227, "", nil,
), "aws_security_group_rule.ingress_with_cidr_blocks[0]").WithParent(causeResourceMeta)

r.OverrideMetadata(types.NewMetadata(types.NewRange(
"terraform-aws-modules/security-group/aws/main.tf", 197, 204, "", nil,
), "aws_security_group_rule.ingress_with_cidr_blocks").WithParent(parentMeta))
return &r
},
expected: []scan.Occurrence{
{
Resource: "aws_security_group_rule.ingress_with_cidr_blocks[0]",
Filename: "terraform-aws-modules/security-group/aws/main.tf",
StartLine: 191,
EndLine: 227,
},
{
Resource: "module.aws-security-groups[\"db1\"]",
Filename: "main.tf",
StartLine: 1,
EndLine: 13,
},
},
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
assert.Equal(t, tt.expected, tt.factory().Occurrences())
})
}
}
10 changes: 7 additions & 3 deletions pkg/scanners/cloudformation/parser/property.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,13 +241,17 @@ func (p *Property) GetProperty(path string) *Property {
pathParts := strings.Split(path, ".")

first := pathParts[0]
var property *Property
property := p

if p.IsNotMap() {
if p.isFunction() {
property, _ = p.resolveValue()
}

if property.IsNotMap() {
return nil
}

for n, p := range p.AsMap() {
for n, p := range property.AsMap() {
if n == first {
property = p
break
Expand Down
75 changes: 75 additions & 0 deletions pkg/scanners/cloudformation/parser/resource_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package parser

import (
"testing"

"github.com/aquasecurity/defsec/pkg/scanners/cloudformation/cftypes"
"github.com/stretchr/testify/require"
)

func Test_GetProperty_PropIsFunction(t *testing.T) {
resource := Resource{
Inner: ResourceInner{
Type: "AWS::S3::Bucket",
Properties: map[string]*Property{
"BucketName": {
Inner: PropertyInner{
Type: cftypes.String,
Value: "mybucket",
},
},
"VersioningConfiguration": {
Inner: PropertyInner{
Type: cftypes.Map,
Value: map[string]*Property{
"Fn::If": {
Inner: PropertyInner{
Type: cftypes.List,
Value: []*Property{
{
Inner: PropertyInner{
Type: cftypes.Bool,
Value: false,
},
},
{
Inner: PropertyInner{
Type: cftypes.Map,
Value: map[string]*Property{
"Status": {
Inner: PropertyInner{
Type: cftypes.String,
Value: "Enabled",
},
},
},
},
},
{
Inner: PropertyInner{
Type: cftypes.Map,
Value: map[string]*Property{
"Status": {
Inner: PropertyInner{
Type: cftypes.String,
Value: "Suspended",
},
},
},
},
},
},
},
},
},
},
},
},
},
}

prop := resource.GetProperty("VersioningConfiguration.Status")
require.NotNil(t, prop)
require.True(t, prop.IsString())
require.Equal(t, "Suspended", prop.AsString())
}

0 comments on commit b31ab1c

Please sign in to comment.