Skip to content
This repository has been archived by the owner on Jun 1, 2022. It is now read-only.

Commit

Permalink
Add the SAM API checks (#28)
Browse files Browse the repository at this point in the history
  • Loading branch information
Owen Rumney authored Dec 2, 2021
1 parent 0452c71 commit c6f5ba7
Show file tree
Hide file tree
Showing 22 changed files with 638 additions and 3 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.16

require (
github.com/apparentlymart/go-cidr v1.1.0
github.com/aquasecurity/defsec v0.0.37
github.com/aquasecurity/defsec v0.0.38-0.20211202114943-52f01d551cdf
github.com/liamg/jfather v0.0.2
github.com/liamg/tml v0.4.0
github.com/spf13/cobra v1.2.1
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ github.com/aquasecurity/defsec v0.0.36 h1:Dq0yRDd7ETN0zi2q+7yeGDSzSU32m2Vw5aMczx
github.com/aquasecurity/defsec v0.0.36/go.mod h1:csaBEcJ3AKy44expnW0dCANEZcS/c1vcJjwBCbnKWBM=
github.com/aquasecurity/defsec v0.0.37 h1:zdZndlKrW257b8VLK1UwfmXiyPuDrNA+wzBilHRk1LA=
github.com/aquasecurity/defsec v0.0.37/go.mod h1:csaBEcJ3AKy44expnW0dCANEZcS/c1vcJjwBCbnKWBM=
github.com/aquasecurity/defsec v0.0.38-0.20211202103545-b5b8849450c9 h1:fgGbzM/N67EfzgPZNQGVHNzeewHnBMJPqYt09fYhFuo=
github.com/aquasecurity/defsec v0.0.38-0.20211202103545-b5b8849450c9/go.mod h1:csaBEcJ3AKy44expnW0dCANEZcS/c1vcJjwBCbnKWBM=
github.com/aquasecurity/defsec v0.0.38-0.20211202114943-52f01d551cdf h1:HD/CwABWPR1iD18Zaf/wPENN6rMKUmyD4RVnlfNMMHQ=
github.com/aquasecurity/defsec v0.0.38-0.20211202114943-52f01d551cdf/go.mod h1:csaBEcJ3AKy44expnW0dCANEZcS/c1vcJjwBCbnKWBM=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
Expand Down
4 changes: 3 additions & 1 deletion internal/app/cfsec/adapter/aws/adapt.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (
"github.com/aquasecurity/cfsec/internal/app/cfsec/adapter/aws/rds"
"github.com/aquasecurity/cfsec/internal/app/cfsec/adapter/aws/redshift"
"github.com/aquasecurity/cfsec/internal/app/cfsec/adapter/aws/s3"
"github.com/aquasecurity/cfsec/internal/app/cfsec/adapter/aws/sam"
"github.com/aquasecurity/cfsec/internal/app/cfsec/adapter/aws/sns"
"github.com/aquasecurity/cfsec/internal/app/cfsec/adapter/aws/sqs"
"github.com/aquasecurity/cfsec/internal/app/cfsec/adapter/aws/ssm"
Expand Down Expand Up @@ -69,10 +70,11 @@ func Adapt(cfFile parser.FileContext) aws.AWS {
RDS: rds.Adapt(cfFile),
Redshift: redshift.Adapt(cfFile),
S3: s3.Adapt(cfFile),
SAM: sam.Adapt(cfFile),
SNS: sns.Adapt(cfFile),
SQS: sqs.Adapt(cfFile),
SSM: ssm.Adapt(cfFile),
VPC: vpc.Adapt(cfFile),
WorkSpaces: workspaces.Adapt(cfFile),
}
}
}
92 changes: 92 additions & 0 deletions internal/app/cfsec/adapter/aws/sam/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package sam

import (
"github.com/aquasecurity/cfsec/internal/app/cfsec/parser"
"github.com/aquasecurity/defsec/provider/aws/sam"
"github.com/aquasecurity/defsec/types"
)

func getApis(cfFile parser.FileContext) (apis []sam.API) {

apiResources := cfFile.GetResourceByType("AWS::Serverless::Api")
for _, r := range apiResources {
api := sam.API{
Metadata: r.Metadata(),
Name: r.GetStringProperty("Name", ""),
TracingEnabled: r.GetBoolProperty("TracingEnabled"),
DomainConfiguration: getDomainConfiguration(r),
AccessLogging: getAccessLogging(r),
RESTMethodSettings: getRestMethodSettings(r),
}

apis = append(apis, api)
}

return apis
}

func getRestMethodSettings(r *parser.Resource) (methodSettings sam.RESTMethodSettings) {

settings := r.GetProperty("MethodSettings")
if settings.IsNil() {
return sam.RESTMethodSettings{
Metadata: r.Metadata(),
CacheDataEncrypted: types.BoolDefault(false, r.Metadata()),
LoggingEnabled: types.BoolDefault(false, r.Metadata()),
DataTraceEnabled: types.BoolDefault(false, r.Metadata()),
MetricsEnabled: types.BoolDefault(false, r.Metadata()),
}
}

loggingEnabled := types.BoolDefault(false, settings.Metadata())
if settings.GetProperty("LoggingLevel").IsNotNil() {
loggingLevel := settings.GetProperty("LoggingLevel")
if settings.GetProperty("LoggingLevel").EqualTo("OFF", parser.IgnoreCase) {
loggingEnabled = types.BoolExplicit(false, loggingLevel.Metadata())
} else {
loggingEnabled = types.BoolExplicit(true, loggingLevel.Metadata())
}

}

return sam.RESTMethodSettings{
Metadata: settings.Metadata(),
CacheDataEncrypted: settings.GetBoolProperty("CacheDataEncrypted"),
LoggingEnabled: loggingEnabled,
DataTraceEnabled: settings.GetBoolProperty("DataTraceEnabled"),
MetricsEnabled: settings.GetBoolProperty("MetricsEnabled"),
}

}

func getAccessLogging(r *parser.Resource) (accessLogging sam.AccessLogging) {

access := r.GetProperty("AccessLogSetting")
if access.IsNil() {
return sam.AccessLogging{
Metadata: r.Metadata(),
CloudwatchLogGroupARN: types.StringDefault("", r.Metadata()),
}
}

return sam.AccessLogging{
Metadata: access.Metadata(),
CloudwatchLogGroupARN: access.GetStringProperty("DestinationArn", ""),
}
}

func getDomainConfiguration(r *parser.Resource) (domainConfig sam.DomainConfiguration) {

domain := r.GetProperty("Domain")
if domain.IsNil() {
domainConfig.SecurityPolicy = types.StringDefault("TLS_1_0", r.Metadata())
return domainConfig
}

return sam.DomainConfiguration{
Metadata: domain.Metadata(),
Name: domain.GetStringProperty("DomainName", ""),
SecurityPolicy: domain.GetStringProperty("SecurityPolicy", "TLS_1_0"),
}

}
22 changes: 22 additions & 0 deletions internal/app/cfsec/adapter/aws/sam/sam.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package sam

import (
"reflect"

"github.com/aquasecurity/cfsec/internal/app/cfsec/debug"
"github.com/aquasecurity/cfsec/internal/app/cfsec/parser"
"github.com/aquasecurity/defsec/provider/aws/sam"
)

// Adapt ...
func Adapt(cfFile parser.FileContext) (sam sam.SAM) {
defer func() {
if r := recover(); r != nil {
metadata := cfFile.Metadata()
debug.Log("There were errors adapting %s from %s", reflect.TypeOf(sam), metadata.Range().GetFilename())
}
}()

sam.APIs = getApis(cfFile)
return sam
}
1 change: 1 addition & 0 deletions internal/app/cfsec/loader/rule_loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
_ "github.com/aquasecurity/cfsec/internal/app/cfsec/rules/aws/rds"
_ "github.com/aquasecurity/cfsec/internal/app/cfsec/rules/aws/redshift"
_ "github.com/aquasecurity/cfsec/internal/app/cfsec/rules/aws/s3"
_ "github.com/aquasecurity/cfsec/internal/app/cfsec/rules/aws/sam"
_ "github.com/aquasecurity/cfsec/internal/app/cfsec/rules/aws/sns"
_ "github.com/aquasecurity/cfsec/internal/app/cfsec/rules/aws/sqs"
_ "github.com/aquasecurity/cfsec/internal/app/cfsec/rules/aws/ssm"
Expand Down
47 changes: 47 additions & 0 deletions internal/app/cfsec/rules/aws/sam/enable_access_logging_rule.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package sam

import (
"github.com/aquasecurity/cfsec/internal/app/cfsec/rules"
"github.com/aquasecurity/cfsec/internal/app/cfsec/scanner"
"github.com/aquasecurity/defsec/rules/aws/sam"
)

func init() {
scanner.RegisterCheckRule(rules.Rule{

BadExample: []string{
`---
AWSTemplateFormatVersion: 2010-09-09
Description: Bad Example of SAM API
Resources:
ApiGatewayApi:
Type: AWS::Serverless::Api
Properties:
Name: Bad SAM API example
StageName: Prod
TracingEnabled: false
`,
},

GoodExample: []string{
`---
AWSTemplateFormatVersion: 2010-09-09
Description: Good Example of SAM API
Resources:
ApiGatewayApi:
Type: AWS::Serverless::Api
Properties:
Name: Good SAM API example
StageName: Prod
TracingEnabled: false
Domain:
SecurityPolicy: TLS_1_2
AccessLogSetting:
DestinationArn: gateway-logging
Format: json
`,
},

Base: sam.CheckEnableAccessLogging,
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package sam

import (
"github.com/aquasecurity/cfsec/internal/app/cfsec/test"
"github.com/aquasecurity/defsec/rules/aws/sam"

"testing"
)

func Test_CheckEnableAccessLogging_FailureExamples(t *testing.T) {
expectedCode := sam.CheckEnableAccessLogging.Rule().LongID()
test.RunFailureExamplesTest(t, expectedCode)
}

func Test_CheckEnableAccessLogging_PassedExamples(t *testing.T) {
expectedCode := sam.CheckEnableAccessLogging.Rule().LongID()
test.RunPassingExamplesTest(t, expectedCode)
}
58 changes: 58 additions & 0 deletions internal/app/cfsec/rules/aws/sam/enable_cache_encryption_rule.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package sam

import (
"github.com/aquasecurity/cfsec/internal/app/cfsec/rules"
"github.com/aquasecurity/cfsec/internal/app/cfsec/scanner"
"github.com/aquasecurity/defsec/rules/aws/sam"
)

func init() {
scanner.RegisterCheckRule(rules.Rule{

BadExample: []string{
`---
AWSTemplateFormatVersion: 2010-09-09
Description: Bad Example of SAM API
Resources:
ApiGatewayApi:
Type: AWS::Serverless::Api
Properties:
Name: Bad SAM API example
StageName: Prod
TracingEnabled: false
`, `---
AWSTemplateFormatVersion: 2010-09-09
Description: Bad Example of SAM API
Resources:
ApiGatewayApi:
Type: AWS::Serverless::Api
Properties:
Name: Bad SAM API example
StageName: Prod
TracingEnabled: false
MethodSettings:
CacheDataEncrypted: false
`,
},

GoodExample: []string{
`---
AWSTemplateFormatVersion: 2010-09-09
Description: Good Example of SAM API
Resources:
ApiGatewayApi:
Type: AWS::Serverless::Api
Properties:
Name: Good SAM API example
StageName: Prod
TracingEnabled: false
Domain:
SecurityPolicy: TLS_1_2
MethodSettings:
CacheDataEncrypted: true
`,
},

Base: sam.CheckEnableCacheEncryption,
})
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package sam

import (
"github.com/aquasecurity/cfsec/internal/app/cfsec/test"
sam "github.com/aquasecurity/defsec/rules/aws/sam"

"testing"
)

func Test_CheckEnableCacheEncryption_FailureExamples(t *testing.T) {
expectedCode := sam.CheckEnableCacheEncryption.Rule().LongID()
test.RunFailureExamplesTest(t, expectedCode)
}

func Test_CheckEnableCacheEncryption_PassedExamples(t *testing.T) {
expectedCode := sam.CheckEnableCacheEncryption.Rule().LongID()
test.RunPassingExamplesTest(t, expectedCode)
}
51 changes: 51 additions & 0 deletions internal/app/cfsec/rules/aws/sam/enable_tracing_rule.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package sam

import (
"github.com/aquasecurity/cfsec/internal/app/cfsec/rules"
"github.com/aquasecurity/cfsec/internal/app/cfsec/scanner"
"github.com/aquasecurity/defsec/rules/aws/sam"
)

func init() {
scanner.RegisterCheckRule(rules.Rule{

BadExample: []string{
`---
AWSTemplateFormatVersion: 2010-09-09
Description: Bad Example of SAM API
Resources:
ApiGatewayApi:
Type: AWS::Serverless::Api
Properties:
Name: Bad SAM API example
StageName: Prod
TracingEnabled: false
`, `---
AWSTemplateFormatVersion: 2010-09-09
Description: Bad Example of SAM API
Resources:
ApiGatewayApi:
Type: AWS::Serverless::Api
Properties:
Name: Bad SAM API example
StageName: Prod
`,
},

GoodExample: []string{
`---
AWSTemplateFormatVersion: 2010-09-09
Description: Good Example of SAM API
Resources:
ApiGatewayApi:
Type: AWS::Serverless::Api
Properties:
Name: Good SAM API example
StageName: Prod
TracingEnabled: true
`,
},

Base: sam.CheckEnableTracing,
})
}
18 changes: 18 additions & 0 deletions internal/app/cfsec/rules/aws/sam/enable_tracing_rule_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package sam

import (
"github.com/aquasecurity/cfsec/internal/app/cfsec/test"
sam "github.com/aquasecurity/defsec/rules/aws/sam"

"testing"
)

func Test_CheckEnableTracing_FailureExamples(t *testing.T) {
expectedCode := sam.CheckEnableTracing.Rule().LongID()
test.RunFailureExamplesTest(t, expectedCode)
}

func Test_CheckEnableTracing_PassedExamples(t *testing.T) {
expectedCode := sam.CheckEnableTracing.Rule().LongID()
test.RunPassingExamplesTest(t, expectedCode)
}
Loading

0 comments on commit c6f5ba7

Please sign in to comment.