From 193ef128524a601ad89c0a81f01004c4785fcb28 Mon Sep 17 00:00:00 2001 From: Nikita Pivkin <100182843+nikpivkin@users.noreply.github.com> Date: Thu, 20 Jul 2023 15:39:37 +0300 Subject: [PATCH] fix(cloudformation): resolve property depending on conditions (#1396) --- .../cloudformation/parser/property.go | 10 ++- .../cloudformation/parser/resource_test.go | 75 +++++++++++++++++++ 2 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 pkg/scanners/cloudformation/parser/resource_test.go diff --git a/pkg/scanners/cloudformation/parser/property.go b/pkg/scanners/cloudformation/parser/property.go index 94abf0609..338d2b737 100644 --- a/pkg/scanners/cloudformation/parser/property.go +++ b/pkg/scanners/cloudformation/parser/property.go @@ -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 diff --git a/pkg/scanners/cloudformation/parser/resource_test.go b/pkg/scanners/cloudformation/parser/resource_test.go new file mode 100644 index 000000000..1636ef9b1 --- /dev/null +++ b/pkg/scanners/cloudformation/parser/resource_test.go @@ -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()) +}