diff --git a/go.mod b/go.mod index d05a43c1..e31d66db 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.16 require ( github.com/apparentlymart/go-cidr v1.1.0 - github.com/aquasecurity/defsec v0.0.38-0.20211202114943-52f01d551cdf + github.com/aquasecurity/defsec v0.0.39 github.com/liamg/jfather v0.0.2 github.com/liamg/tml v0.4.0 github.com/spf13/cobra v1.2.1 diff --git a/go.sum b/go.sum index e52028d9..859c23d6 100644 --- a/go.sum +++ b/go.sum @@ -62,6 +62,30 @@ github.com/aquasecurity/defsec v0.0.38-0.20211202103545-b5b8849450c9 h1:fgGbzM/N 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/aquasecurity/defsec v0.0.38-0.20211202150847-444824e0b664 h1:YzvRYLmu3deyC4Wf6QrWvcb3iqgc2RTVHHiTykdZbcY= +github.com/aquasecurity/defsec v0.0.38-0.20211202150847-444824e0b664/go.mod h1:csaBEcJ3AKy44expnW0dCANEZcS/c1vcJjwBCbnKWBM= +github.com/aquasecurity/defsec v0.0.38-0.20211202151317-49073d729686 h1:Rf3UdwpQu6rqlUfSg6VcUABb587D4th8gN6H2m0ClrU= +github.com/aquasecurity/defsec v0.0.38-0.20211202151317-49073d729686/go.mod h1:csaBEcJ3AKy44expnW0dCANEZcS/c1vcJjwBCbnKWBM= +github.com/aquasecurity/defsec v0.0.38-0.20211202154419-d594e7f5da4a h1:WCMe4TmD/FFyo3PVNwFu2bCN7Qa55mACI/tN64b4+tI= +github.com/aquasecurity/defsec v0.0.38-0.20211202154419-d594e7f5da4a/go.mod h1:csaBEcJ3AKy44expnW0dCANEZcS/c1vcJjwBCbnKWBM= +github.com/aquasecurity/defsec v0.0.38-0.20211202154813-a8f06cb40d8d h1:OthlJ7rVpC0S8F+qUDuehcVEW/JG3CJ59vg2OdaKbpA= +github.com/aquasecurity/defsec v0.0.38-0.20211202154813-a8f06cb40d8d/go.mod h1:csaBEcJ3AKy44expnW0dCANEZcS/c1vcJjwBCbnKWBM= +github.com/aquasecurity/defsec v0.0.38-0.20211202160241-d83b25ead044 h1:rRKkBKMz0dZpMNEZq/kzI7DmvrUihrGeUSDVtct2ep0= +github.com/aquasecurity/defsec v0.0.38-0.20211202160241-d83b25ead044/go.mod h1:csaBEcJ3AKy44expnW0dCANEZcS/c1vcJjwBCbnKWBM= +github.com/aquasecurity/defsec v0.0.38-0.20211202161757-d84ca68f3ae0 h1:Q15KxrS4BSe3nnet/6tmUniq+aJcuLrEm5NLCSgkY7o= +github.com/aquasecurity/defsec v0.0.38-0.20211202161757-d84ca68f3ae0/go.mod h1:csaBEcJ3AKy44expnW0dCANEZcS/c1vcJjwBCbnKWBM= +github.com/aquasecurity/defsec v0.0.38-0.20211202165623-c5c733e8f427 h1:CEF+BseRwkazD+2KIeZaBDXFGhcRS0uEdzvx8ckQB4E= +github.com/aquasecurity/defsec v0.0.38-0.20211202165623-c5c733e8f427/go.mod h1:csaBEcJ3AKy44expnW0dCANEZcS/c1vcJjwBCbnKWBM= +github.com/aquasecurity/defsec v0.0.38-0.20211202165845-4b964f19ef54 h1:FMXpegDORcyzyS+Set/1UMEfpC+7jYcO1d5rO5RD+3s= +github.com/aquasecurity/defsec v0.0.38-0.20211202165845-4b964f19ef54/go.mod h1:csaBEcJ3AKy44expnW0dCANEZcS/c1vcJjwBCbnKWBM= +github.com/aquasecurity/defsec v0.0.38-0.20211202170330-25a726735d94 h1:gRwq7flkNBu01SccjpMn4H4MPSltmPqXx1px/E+j2zw= +github.com/aquasecurity/defsec v0.0.38-0.20211202170330-25a726735d94/go.mod h1:csaBEcJ3AKy44expnW0dCANEZcS/c1vcJjwBCbnKWBM= +github.com/aquasecurity/defsec v0.0.38-0.20211202171943-fc8aa959d2b3 h1:5mj9J/bd9NXS6/MWL7SYWCuX1WeBmB5uGX5UuT/t4/E= +github.com/aquasecurity/defsec v0.0.38-0.20211202171943-fc8aa959d2b3/go.mod h1:csaBEcJ3AKy44expnW0dCANEZcS/c1vcJjwBCbnKWBM= +github.com/aquasecurity/defsec v0.0.38 h1:nIxKDsJNatjbZ7XA6uQ0mnPSnKpCJsZt4CoDlr2UOBE= +github.com/aquasecurity/defsec v0.0.38/go.mod h1:csaBEcJ3AKy44expnW0dCANEZcS/c1vcJjwBCbnKWBM= +github.com/aquasecurity/defsec v0.0.39 h1:C89/VOojkIb0MZBXHZ/vrlSW+DeEy42w+mg6vwjenI4= +github.com/aquasecurity/defsec v0.0.39/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= diff --git a/internal/app/cfsec/adapter/aws/sam/function.go b/internal/app/cfsec/adapter/aws/sam/function.go new file mode 100644 index 00000000..05f5be60 --- /dev/null +++ b/internal/app/cfsec/adapter/aws/sam/function.go @@ -0,0 +1,55 @@ +package sam + +import ( + "github.com/aquasecurity/cfsec/internal/app/cfsec/parser" + "github.com/aquasecurity/cfsec/internal/app/cfsec/util" + "github.com/aquasecurity/defsec/provider/aws/iam" + "github.com/aquasecurity/defsec/provider/aws/sam" +) + +func getFunctions(cfFile parser.FileContext) (functions []sam.Function) { + + functionResources := cfFile.GetResourceByType("AWS::Serverless::Function") + for _, r := range functionResources { + function := sam.Function{ + Metadata: r.Metadata(), + FunctionName: r.GetStringProperty("FunctionName"), + Tracing: r.GetStringProperty("Tracing", sam.TracingModePassThrough), + } + + setFunctionPolicies(r, &function) + functions = append(functions, function) + } + + return functions +} + +func setFunctionPolicies(r *parser.Resource, function *sam.Function) { + policies := r.GetProperty("Policies") + if policies.IsNotNil() { + if policies.IsString() { + function.ManagedPolicies = append(function.ManagedPolicies, policies.AsStringValue()) + } else if policies.IsList() { + for _, property := range policies.AsList() { + if property.IsMap() { + policyDoc, err := getPolicyDocument(property, r.SourceFormat()) + if err != nil { + + function.ManagedPolicies = append(function.ManagedPolicies, property.AsStringValue()) + continue + } + function.Policies = append(function.Policies, *policyDoc) + } else { + function.ManagedPolicies = append(function.ManagedPolicies, property.AsStringValue()) + } + + } + } + } +} + +func getPolicyDocument(policyProp *parser.Property, sourceFormat parser.SourceFormat) (*iam.PolicyDocument, error) { + policyDoc := util.GetJsonBytes(policyProp, sourceFormat, true) + + return iam.ParsePolicyDocument(policyDoc, policyProp.Metadata()) +} diff --git a/internal/app/cfsec/adapter/aws/sam/http_api.go b/internal/app/cfsec/adapter/aws/sam/http_api.go new file mode 100644 index 00000000..4dfdd714 --- /dev/null +++ b/internal/app/cfsec/adapter/aws/sam/http_api.go @@ -0,0 +1,45 @@ +package sam + +import ( + "github.com/aquasecurity/cfsec/internal/app/cfsec/parser" + "github.com/aquasecurity/defsec/provider/aws/sam" + "github.com/aquasecurity/defsec/types" +) + +func getHttpApis(cfFile parser.FileContext) (apis []sam.HttpAPI) { + + apiResources := cfFile.GetResourceByType("AWS::Serverless::HttpApi") + for _, r := range apiResources { + api := sam.HttpAPI{ + Metadata: r.Metadata(), + Name: r.GetStringProperty("Name", ""), + DomainConfiguration: getDomainConfiguration(r), + AccessLogging: getAccessLogging(r), + DefaultRouteSettings: getRouteSettings(r), + } + + apis = append(apis, api) + } + + return apis +} + +func getRouteSettings(r *parser.Resource) sam.RouteSettings { + + route := r.GetProperty("DefaultRouteSettings") + if route.IsNil() { + return sam.RouteSettings{ + Metadata: r.Metadata(), + LoggingEnabled: types.BoolDefault(false, r.Metadata()), + DataTraceEnabled: types.BoolDefault(false, r.Metadata()), + DetailedMetricsEnabled: types.BoolDefault(false, r.Metadata()), + } + } + + return sam.RouteSettings{ + Metadata: route.Metadata(), + LoggingEnabled: route.GetBoolProperty("LoggingLevel"), + DataTraceEnabled: route.GetBoolProperty("DataTraceEnabled"), + DetailedMetricsEnabled: route.GetBoolProperty("DetailedMetricsEnabled"), + } +} diff --git a/internal/app/cfsec/adapter/aws/sam/sam.go b/internal/app/cfsec/adapter/aws/sam/sam.go index 8f2fdd3b..207f5e9d 100644 --- a/internal/app/cfsec/adapter/aws/sam/sam.go +++ b/internal/app/cfsec/adapter/aws/sam/sam.go @@ -18,5 +18,9 @@ func Adapt(cfFile parser.FileContext) (sam sam.SAM) { }() sam.APIs = getApis(cfFile) + sam.HttpAPIs = getHttpApis(cfFile) + sam.Functions = getFunctions(cfFile) + sam.StateMachines = getStateMachines(cfFile) + sam.SimpleTables = getSimpleTables(cfFile) return sam } diff --git a/internal/app/cfsec/adapter/aws/sam/state_machines.go b/internal/app/cfsec/adapter/aws/sam/state_machines.go new file mode 100644 index 00000000..93cf9634 --- /dev/null +++ b/internal/app/cfsec/adapter/aws/sam/state_machines.go @@ -0,0 +1,59 @@ +package sam + +import ( + "github.com/aquasecurity/cfsec/internal/app/cfsec/parser" + "github.com/aquasecurity/defsec/provider/aws/sam" + "github.com/aquasecurity/defsec/types" +) + +func getStateMachines(cfFile parser.FileContext) (stateMachines []sam.StateMachine) { + + stateMachineResources := cfFile.GetResourceByType("AWS::Serverless::StateMachine") + for _, r := range stateMachineResources { + stateMachine := sam.StateMachine{ + Metadata: r.Metadata(), + Name: r.GetStringProperty("Name"), + LoggingConfiguration: sam.LoggingConfiguration{}, + Tracing: getTracingConfiguration(r), + } + + setStateMachinePolicies(r, &stateMachine) + stateMachines = append(stateMachines, stateMachine) + } + + return stateMachines +} + +func getTracingConfiguration(r *parser.Resource) sam.TracingConfiguration { + tracing := r.GetProperty("Tracing") + if tracing.IsNil() { + return sam.TracingConfiguration{ + Metadata: r.Metadata(), + Enabled: types.BoolDefault(false, r.Metadata()), + } + } + + return sam.TracingConfiguration{ + Metadata: tracing.Metadata(), + Enabled: tracing.GetBoolProperty("Enabled"), + } +} + +func setStateMachinePolicies(r *parser.Resource, stateMachine *sam.StateMachine) { + policies := r.GetProperty("Policies") + if policies.IsNotNil() { + if policies.IsString() { + stateMachine.ManagedPolicies = append(stateMachine.ManagedPolicies, policies.AsStringValue()) + } else if policies.IsList() { + for _, property := range policies.AsList() { + policyDoc, err := getPolicyDocument(property, r.SourceFormat()) + if err != nil { + + stateMachine.ManagedPolicies = append(stateMachine.ManagedPolicies, property.AsStringValue()) + continue + } + stateMachine.Policies = append(stateMachine.Policies, *policyDoc) + } + } + } +} diff --git a/internal/app/cfsec/adapter/aws/sam/tables.go b/internal/app/cfsec/adapter/aws/sam/tables.go new file mode 100644 index 00000000..0d4403fc --- /dev/null +++ b/internal/app/cfsec/adapter/aws/sam/tables.go @@ -0,0 +1,40 @@ +package sam + +import ( + "github.com/aquasecurity/cfsec/internal/app/cfsec/parser" + "github.com/aquasecurity/defsec/provider/aws/sam" + "github.com/aquasecurity/defsec/types" +) + +func getSimpleTables(cfFile parser.FileContext) (tables []sam.SimpleTable) { + + tableResources := cfFile.GetResourceByType("AWS::Serverless::SimpleTable") + for _, r := range tableResources { + table := sam.SimpleTable{ + Metadata: r.Metadata(), + TableName: r.GetStringProperty("TableName"), + SSESpecification: getSSESpecification(r), + } + + tables = append(tables, table) + } + + return tables +} + +func getSSESpecification(r *parser.Resource) sam.SSESpecification { + sse := r.GetProperty("SSESpecification") + if sse.IsNil() { + return sam.SSESpecification{ + Metadata: r.Metadata(), + Enabled: types.BoolDefault(false, r.Metadata()), + KMSMasterKeyID: types.StringDefault("", r.Metadata()), + } + } + + return sam.SSESpecification{ + Metadata: sse.Metadata(), + Enabled: sse.GetBoolProperty("SSEEnabled"), + KMSMasterKeyID: sse.GetStringProperty("KMSMasterKeyID"), + } +} diff --git a/internal/app/cfsec/rules/aws/sam/use_secure_tls_rule.go b/internal/app/cfsec/rules/aws/sam/api_use_secure_tls_rule.go similarity index 95% rename from internal/app/cfsec/rules/aws/sam/use_secure_tls_rule.go rename to internal/app/cfsec/rules/aws/sam/api_use_secure_tls_rule.go index 8dbd9185..4a125d2c 100644 --- a/internal/app/cfsec/rules/aws/sam/use_secure_tls_rule.go +++ b/internal/app/cfsec/rules/aws/sam/api_use_secure_tls_rule.go @@ -39,6 +39,6 @@ Resources: `, }, - Base: sam.CheckUseSecureTlsPolicy, + Base: sam.CheckApiUseSecureTlsPolicy, }) } diff --git a/internal/app/cfsec/rules/aws/sam/api_use_secure_tls_rule_test.go b/internal/app/cfsec/rules/aws/sam/api_use_secure_tls_rule_test.go new file mode 100644 index 00000000..6a9ae9a6 --- /dev/null +++ b/internal/app/cfsec/rules/aws/sam/api_use_secure_tls_rule_test.go @@ -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_CheckApiUseSecureTlsPolicy_FailureExamples(t *testing.T) { + expectedCode := sam.CheckApiUseSecureTlsPolicy.Rule().LongID() + test.RunFailureExamplesTest(t, expectedCode) +} + +func Test_CheckApiUseSecureTlsPolicy_PassedExamples(t *testing.T) { + expectedCode := sam.CheckApiUseSecureTlsPolicy.Rule().LongID() + test.RunPassingExamplesTest(t, expectedCode) +} diff --git a/internal/app/cfsec/rules/aws/sam/enable_access_logging_rule_test.go b/internal/app/cfsec/rules/aws/sam/enable_access_logging_rule_test.go deleted file mode 100644 index 2efbffd7..00000000 --- a/internal/app/cfsec/rules/aws/sam/enable_access_logging_rule_test.go +++ /dev/null @@ -1,18 +0,0 @@ -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) -} diff --git a/internal/app/cfsec/rules/aws/sam/enable_access_logging_rule.go b/internal/app/cfsec/rules/aws/sam/enable_api_access_logging_rule.go similarity index 95% rename from internal/app/cfsec/rules/aws/sam/enable_access_logging_rule.go rename to internal/app/cfsec/rules/aws/sam/enable_api_access_logging_rule.go index a981fcd2..6ac15349 100644 --- a/internal/app/cfsec/rules/aws/sam/enable_access_logging_rule.go +++ b/internal/app/cfsec/rules/aws/sam/enable_api_access_logging_rule.go @@ -42,6 +42,6 @@ Resources: `, }, - Base: sam.CheckEnableAccessLogging, + Base: sam.CheckEnableApiAccessLogging, }) } diff --git a/internal/app/cfsec/rules/aws/sam/enable_api_access_logging_rule_test.go b/internal/app/cfsec/rules/aws/sam/enable_api_access_logging_rule_test.go new file mode 100644 index 00000000..5f917a35 --- /dev/null +++ b/internal/app/cfsec/rules/aws/sam/enable_api_access_logging_rule_test.go @@ -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_CheckEnableApiAccessLogging_FailureExamples(t *testing.T) { + expectedCode := sam.CheckEnableApiAccessLogging.Rule().LongID() + test.RunFailureExamplesTest(t, expectedCode) +} + +func Test_CheckEnableApiAccessLogging_PassedExamples(t *testing.T) { + expectedCode := sam.CheckEnableApiAccessLogging.Rule().LongID() + test.RunPassingExamplesTest(t, expectedCode) +} diff --git a/internal/app/cfsec/rules/aws/sam/enable_cache_encryption_rule.go b/internal/app/cfsec/rules/aws/sam/enable_api_cache_encryption_rule.go similarity index 96% rename from internal/app/cfsec/rules/aws/sam/enable_cache_encryption_rule.go rename to internal/app/cfsec/rules/aws/sam/enable_api_cache_encryption_rule.go index 3082e3fc..88d2456c 100644 --- a/internal/app/cfsec/rules/aws/sam/enable_cache_encryption_rule.go +++ b/internal/app/cfsec/rules/aws/sam/enable_api_cache_encryption_rule.go @@ -53,6 +53,6 @@ Resources: `, }, - Base: sam.CheckEnableCacheEncryption, + Base: sam.CheckEnableApiCacheEncryption, }) } diff --git a/internal/app/cfsec/rules/aws/sam/enable_api_cache_encryption_rule_test.go b/internal/app/cfsec/rules/aws/sam/enable_api_cache_encryption_rule_test.go new file mode 100644 index 00000000..d1a51730 --- /dev/null +++ b/internal/app/cfsec/rules/aws/sam/enable_api_cache_encryption_rule_test.go @@ -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_CheckEnableApiCacheEncryption_FailureExamples(t *testing.T) { + expectedCode := sam.CheckEnableApiCacheEncryption.Rule().LongID() + test.RunFailureExamplesTest(t, expectedCode) +} + +func Test_CheckEnableApiCacheEncryption_PassedExamples(t *testing.T) { + expectedCode := sam.CheckEnableApiCacheEncryption.Rule().LongID() + test.RunPassingExamplesTest(t, expectedCode) +} diff --git a/internal/app/cfsec/rules/aws/sam/enable_tracing_rule.go b/internal/app/cfsec/rules/aws/sam/enable_api_tracing_rule.go similarity index 96% rename from internal/app/cfsec/rules/aws/sam/enable_tracing_rule.go rename to internal/app/cfsec/rules/aws/sam/enable_api_tracing_rule.go index 913b1ca5..d7649710 100644 --- a/internal/app/cfsec/rules/aws/sam/enable_tracing_rule.go +++ b/internal/app/cfsec/rules/aws/sam/enable_api_tracing_rule.go @@ -46,6 +46,6 @@ Resources: `, }, - Base: sam.CheckEnableTracing, + Base: sam.CheckEnableApiTracing, }) } diff --git a/internal/app/cfsec/rules/aws/sam/enable_api_tracing_rule_test.go b/internal/app/cfsec/rules/aws/sam/enable_api_tracing_rule_test.go new file mode 100644 index 00000000..5e03fec1 --- /dev/null +++ b/internal/app/cfsec/rules/aws/sam/enable_api_tracing_rule_test.go @@ -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_CheckEnableApiTracingFailureExamples(t *testing.T) { + expectedCode := sam.CheckEnableApiTracing.Rule().LongID() + test.RunFailureExamplesTest(t, expectedCode) +} + +func Test_CheckEnableApiTracing_PassedExamples(t *testing.T) { + expectedCode := sam.CheckEnableApiTracing.Rule().LongID() + test.RunPassingExamplesTest(t, expectedCode) +} diff --git a/internal/app/cfsec/rules/aws/sam/enable_cache_encryption_rule_test.go b/internal/app/cfsec/rules/aws/sam/enable_cache_encryption_rule_test.go deleted file mode 100644 index 3cde3f2b..00000000 --- a/internal/app/cfsec/rules/aws/sam/enable_cache_encryption_rule_test.go +++ /dev/null @@ -1,18 +0,0 @@ -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) -} diff --git a/internal/app/cfsec/rules/aws/sam/enable_function_tracing_rule.go b/internal/app/cfsec/rules/aws/sam/enable_function_tracing_rule.go new file mode 100644 index 00000000..7c5186c8 --- /dev/null +++ b/internal/app/cfsec/rules/aws/sam/enable_function_tracing_rule.go @@ -0,0 +1,53 @@ +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 Function +Resources: + BadFunction: + Type: AWS::Serverless::Function + Properties: + PackageType: Image + ImageUri: account-id.dkr.ecr.region.amazonaws.com/ecr-repo-name:image-name + ImageConfig: + Command: + - "app.lambda_handler" + EntryPoint: + - "entrypoint1" + WorkingDirectory: "workDir" +`, + }, + + GoodExample: []string{ + `--- +AWSTemplateFormatVersion: 2010-09-09 +Description: Good Example of SAM Function +Resources: + GoodFunction: + Type: AWS::Serverless::Function + Properties: + PackageType: Image + ImageUri: account-id.dkr.ecr.region.amazonaws.com/ecr-repo-name:image-name + ImageConfig: + Command: + - "app.lambda_handler" + EntryPoint: + - "entrypoint1" + WorkingDirectory: "workDir" + Tracing: Active +`, + }, + + Base: sam.CheckEnableFunctionTracing, + }) +} diff --git a/internal/app/cfsec/rules/aws/sam/enable_function_tracing_rule_test.go b/internal/app/cfsec/rules/aws/sam/enable_function_tracing_rule_test.go new file mode 100644 index 00000000..cb801e70 --- /dev/null +++ b/internal/app/cfsec/rules/aws/sam/enable_function_tracing_rule_test.go @@ -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_CheckEnableFunctionTracing_FailureExamples(t *testing.T) { + expectedCode := sam.CheckEnableFunctionTracing.Rule().LongID() + test.RunFailureExamplesTest(t, expectedCode) +} + +func Test_CheckEnableFunctionTracing_PassedExamples(t *testing.T) { + expectedCode := sam.CheckEnableFunctionTracing.Rule().LongID() + test.RunPassingExamplesTest(t, expectedCode) +} diff --git a/internal/app/cfsec/rules/aws/sam/enable_http_api_access_logging_rule.go b/internal/app/cfsec/rules/aws/sam/enable_http_api_access_logging_rule.go new file mode 100644 index 00000000..861cde5c --- /dev/null +++ b/internal/app/cfsec/rules/aws/sam/enable_http_api_access_logging_rule.go @@ -0,0 +1,46 @@ +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: + HttpApi: + Type: AWS::Serverless::HttpApi + Properties: + Properties: + Name: Good SAM API example + StageName: Prod + Tracing: Passthrough +`, + }, + + GoodExample: []string{ + `--- +AWSTemplateFormatVersion: 2010-09-09 +Description: Good Example of SAM API +Resources: + ApiGatewayApi: + Type: AWS::Serverless::HttpApi + Properties: + Name: Good SAM API example + StageName: Prod + Tracing: Activey + AccessLogSetting: + DestinationArn: gateway-logging + Format: json +`, + }, + + Base: sam.CheckEnableHttpApiAccessLogging, + }) +} diff --git a/internal/app/cfsec/rules/aws/sam/enable_http_api_access_logging_rule_test.go b/internal/app/cfsec/rules/aws/sam/enable_http_api_access_logging_rule_test.go new file mode 100644 index 00000000..756dc74a --- /dev/null +++ b/internal/app/cfsec/rules/aws/sam/enable_http_api_access_logging_rule_test.go @@ -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_CheckEnableHttpApiAccessLogging_FailureExamples(t *testing.T) { + expectedCode := sam.CheckEnableApiAccessLogging.Rule().LongID() + test.RunFailureExamplesTest(t, expectedCode) +} + +func Test_CheckEnableHttpApiAccessLogging_PassedExamples(t *testing.T) { + expectedCode := sam.CheckEnableHttpApiAccessLogging.Rule().LongID() + test.RunPassingExamplesTest(t, expectedCode) +} diff --git a/internal/app/cfsec/rules/aws/sam/enable_state_machine_tracing_rule.go b/internal/app/cfsec/rules/aws/sam/enable_state_machine_tracing_rule.go new file mode 100644 index 00000000..cc2a0ff0 --- /dev/null +++ b/internal/app/cfsec/rules/aws/sam/enable_state_machine_tracing_rule.go @@ -0,0 +1,71 @@ +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: + BadStateMachine: + Type: AWS::Serverless::StateMachine + Properties: + Definition: + StartAt: MyLambdaState + States: + MyLambdaState: + Type: Task + Resource: arn:aws:lambda:us-east-1:123456123456:function:my-sample-lambda-app + End: true + Role: arn:aws:iam::123456123456:role/service-role/my-sample-role + Tracing: + Enabled: false +`, `--- +AWSTemplateFormatVersion: 2010-09-09 +Description: Bad Example of SAM API +Resources: + BadStateMachine: + Type: AWS::Serverless::StateMachine + Properties: + Definition: + StartAt: MyLambdaState + States: + MyLambdaState: + Type: Task + Resource: arn:aws:lambda:us-east-1:123456123456:function:my-sample-lambda-app + End: true + Role: arn:aws:iam::123456123456:role/service-role/my-sample-role +`, + }, + + GoodExample: []string{ + `--- +AWSTemplateFormatVersion: 2010-09-09 +Description: Good Example of SAM API +Resources: + GoodStateMachine: + Type: AWS::Serverless::StateMachine + Properties: + Definition: + StartAt: MyLambdaState + States: + MyLambdaState: + Type: Task + Resource: arn:aws:lambda:us-east-1:123456123456:function:my-sample-lambda-app + End: true + Role: arn:aws:iam::123456123456:role/service-role/my-sample-role + Tracing: + Enabled: true +`, + }, + + Base: sam.CheckEnableStateMachineTracing, + }) +} diff --git a/internal/app/cfsec/rules/aws/sam/enable_state_machine_tracing_rule_test.go b/internal/app/cfsec/rules/aws/sam/enable_state_machine_tracing_rule_test.go new file mode 100644 index 00000000..ac3250be --- /dev/null +++ b/internal/app/cfsec/rules/aws/sam/enable_state_machine_tracing_rule_test.go @@ -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_CheckEnableStateMachineTracing_FailureExamples(t *testing.T) { + expectedCode := sam.CheckEnableStateMachineTracing.Rule().LongID() + test.RunFailureExamplesTest(t, expectedCode) +} + +func Test_CheckEnableStateMachineTracing_PassedExamples(t *testing.T) { + expectedCode := sam.CheckEnableStateMachineTracing.Rule().LongID() + test.RunPassingExamplesTest(t, expectedCode) +} diff --git a/internal/app/cfsec/rules/aws/sam/enable_table_encryption_rule.go b/internal/app/cfsec/rules/aws/sam/enable_table_encryption_rule.go new file mode 100644 index 00000000..7ceaf553 --- /dev/null +++ b/internal/app/cfsec/rules/aws/sam/enable_table_encryption_rule.go @@ -0,0 +1,50 @@ +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 Table +Resources: + BadFunction: + Type: AWS::Serverless::SimpleTable + Properties: + TableName: Bad Table + SSESpecification: + SSEEnabled: false +`, `--- +AWSTemplateFormatVersion: 2010-09-09 +Description: Bad Example of SAM Table +Resources: + BadFunction: + Type: AWS::Serverless::SimpleTable + Properties: + TableName: Bad Table +`, + }, + + GoodExample: []string{ + `--- +AWSTemplateFormatVersion: 2010-09-09 +Description: Good Example of SAM Table +Resources: + GoodFunction: + Type: AWS::Serverless::SimpleTable + Properties: + TableName: GoodTable + SSESpecification: + SSEEnabled: true +`, + }, + + Base: sam.CheckEnableTableEncryption, + }) +} diff --git a/internal/app/cfsec/rules/aws/sam/enable_table_encryption_rule_test.go b/internal/app/cfsec/rules/aws/sam/enable_table_encryption_rule_test.go new file mode 100644 index 00000000..c4a42292 --- /dev/null +++ b/internal/app/cfsec/rules/aws/sam/enable_table_encryption_rule_test.go @@ -0,0 +1,18 @@ +package sam + +import ( + "testing" + + "github.com/aquasecurity/cfsec/internal/app/cfsec/test" + "github.com/aquasecurity/defsec/rules/aws/sam" +) + +func Test_CheckEnableTableEncryption_FailureExamples(t *testing.T) { + expectedCode := sam.CheckEnableTableEncryption.Rule().LongID() + test.RunFailureExamplesTest(t, expectedCode) +} + +func Test_CheckEnableTableEncryption_PassedExamples(t *testing.T) { + expectedCode := sam.CheckEnableTableEncryption.Rule().LongID() + test.RunPassingExamplesTest(t, expectedCode) +} diff --git a/internal/app/cfsec/rules/aws/sam/enable_tracing_rule_test.go b/internal/app/cfsec/rules/aws/sam/enable_tracing_rule_test.go deleted file mode 100644 index 74dbf732..00000000 --- a/internal/app/cfsec/rules/aws/sam/enable_tracing_rule_test.go +++ /dev/null @@ -1,18 +0,0 @@ -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) -} diff --git a/internal/app/cfsec/rules/aws/sam/no_function_policy_wildcards_rule.go b/internal/app/cfsec/rules/aws/sam/no_function_policy_wildcards_rule.go new file mode 100644 index 00000000..2d21f93e --- /dev/null +++ b/internal/app/cfsec/rules/aws/sam/no_function_policy_wildcards_rule.go @@ -0,0 +1,69 @@ +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 Function +Resources: + BadFunction: + Type: AWS::Serverless::Function + Properties: + PackageType: Image + ImageUri: account-id.dkr.ecr.region.amazonaws.com/ecr-repo-name:image-name + ImageConfig: + Command: + - "app.lambda_handler" + EntryPoint: + - "entrypoint1" + WorkingDirectory: "workDir" + Policies: + - AWSLambdaExecute + - Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - s3:* + Resource: 'arn:aws:s3:::my-bucket/*' +`, + }, + + GoodExample: []string{ + `--- +AWSTemplateFormatVersion: 2010-09-09 +Description: Good Example of SAM Function +Resources: + GoodFunction: + Type: AWS::Serverless::Function + Properties: + PackageType: Image + ImageUri: account-id.dkr.ecr.region.amazonaws.com/ecr-repo-name:image-name + ImageConfig: + Command: + - "app.lambda_handler" + EntryPoint: + - "entrypoint1" + WorkingDirectory: "workDir" + Policies: + - AWSLambdaExecute + - Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - s3:GetObject + - s3:GetObjectACL + Resource: 'arn:aws:s3:::my-bucket/*' +`, + }, + + Base: sam.CheckNoFunctionPolicyWildcards, + }) +} diff --git a/internal/app/cfsec/rules/aws/sam/no_function_policy_wildcards_rule_test.go b/internal/app/cfsec/rules/aws/sam/no_function_policy_wildcards_rule_test.go new file mode 100644 index 00000000..d8176692 --- /dev/null +++ b/internal/app/cfsec/rules/aws/sam/no_function_policy_wildcards_rule_test.go @@ -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_CheckNoFunctionPolicyWildcards_FailureExamples(t *testing.T) { + expectedCode := sam.CheckNoFunctionPolicyWildcards.Rule().LongID() + test.RunFailureExamplesTest(t, expectedCode) +} + +func Test_CheckNoFunctionPolicyWildcards_PassedExamples(t *testing.T) { + expectedCode := sam.CheckNoFunctionPolicyWildcards.Rule().LongID() + test.RunPassingExamplesTest(t, expectedCode) +} diff --git a/internal/app/cfsec/rules/aws/sam/no_state_machine_policy_wildcards_rule.go b/internal/app/cfsec/rules/aws/sam/no_state_machine_policy_wildcards_rule.go new file mode 100644 index 00000000..426b07b2 --- /dev/null +++ b/internal/app/cfsec/rules/aws/sam/no_state_machine_policy_wildcards_rule.go @@ -0,0 +1,73 @@ +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 Function +Resources: + BadFunction: + Type: AWS::Serverless::StateMachine + Properties: + Definition: + StartAt: MyLambdaState + States: + MyLambdaState: + Type: Task + Resource: arn:aws:lambda:us-east-1:123456123456:function:my-sample-lambda-app + End: true + Role: arn:aws:iam::123456123456:role/service-role/my-sample-role + Tracing: + Enabled: true + Policies: + - AWSLambdaExecute + - Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - s3:* + Resource: 'arn:aws:s3:::my-bucket/*' +`, + }, + + GoodExample: []string{ + `--- +AWSTemplateFormatVersion: 2010-09-09 +Description: Good Example of SAM Function +Resources: + GoodFunction: + Type: AWS::Serverless::StateMachine + Properties: + Definition: + StartAt: MyLambdaState + States: + MyLambdaState: + Type: Task + Resource: arn:aws:lambda:us-east-1:123456123456:function:my-sample-lambda-app + End: true + Role: arn:aws:iam::123456123456:role/service-role/my-sample-role + Tracing: + Enabled: true + Policies: + - AWSLambdaExecute + - Version: '2012-10-17' + Statement: + - Effect: Allow + Action: + - s3:GetObject + - s3:GetObjectACL + Resource: 'arn:aws:s3:::my-bucket/*' +`, + }, + + Base: sam.CheckNoStateMachinePolicyWildcards, + }) +} diff --git a/internal/app/cfsec/rules/aws/sam/no_state_machine_policy_wildcards_rule_test.go b/internal/app/cfsec/rules/aws/sam/no_state_machine_policy_wildcards_rule_test.go new file mode 100644 index 00000000..00fd8b92 --- /dev/null +++ b/internal/app/cfsec/rules/aws/sam/no_state_machine_policy_wildcards_rule_test.go @@ -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_CheckNoStateMachinePolicyWildcards_FailureExamples(t *testing.T) { + expectedCode := sam.CheckNoStateMachinePolicyWildcards.Rule().LongID() + test.RunFailureExamplesTest(t, expectedCode) +} + +func Test_CheckNoStateMachinePolicyWildcards_PassedExamples(t *testing.T) { + expectedCode := sam.CheckNoStateMachinePolicyWildcards.Rule().LongID() + test.RunPassingExamplesTest(t, expectedCode) +} diff --git a/internal/app/cfsec/rules/aws/sam/use_secure_tls_rule_test.go b/internal/app/cfsec/rules/aws/sam/use_secure_tls_rule_test.go deleted file mode 100644 index 4bd10ed4..00000000 --- a/internal/app/cfsec/rules/aws/sam/use_secure_tls_rule_test.go +++ /dev/null @@ -1,18 +0,0 @@ -package sam - -import ( - "github.com/aquasecurity/cfsec/internal/app/cfsec/test" - sam "github.com/aquasecurity/defsec/rules/aws/sam" - - "testing" -) - -func Test_CheckUseSecureTlsPolicy_FailureExamples(t *testing.T) { - expectedCode := sam.CheckUseSecureTlsPolicy.Rule().LongID() - test.RunFailureExamplesTest(t, expectedCode) -} - -func Test_CheckUseSecureTlsPolicy_PassedExamples(t *testing.T) { - expectedCode := sam.CheckUseSecureTlsPolicy.Rule().LongID() - test.RunPassingExamplesTest(t, expectedCode) -} diff --git a/internal/app/cfsec/util/json_blob_extractor.go b/internal/app/cfsec/util/json_blob_extractor.go index 39fc80f3..9cf697d9 100644 --- a/internal/app/cfsec/util/json_blob_extractor.go +++ b/internal/app/cfsec/util/json_blob_extractor.go @@ -9,7 +9,7 @@ import ( ) // GetJsonBytes ... -func GetJsonBytes(policyProp *parser.Property, format parser.SourceFormat) []byte { +func GetJsonBytes(policyProp *parser.Property, format parser.SourceFormat, squashList ...bool) []byte { lines, err := policyProp.AsRawStrings() if err != nil { return nil @@ -18,6 +18,10 @@ func GetJsonBytes(policyProp *parser.Property, format parser.SourceFormat) []byt return []byte(strings.Join(lines, " ")) } + if len(squashList) > 0 { + lines[0] = strings.Replace(lines[0], "-", " ", 1) + } + lines = removeLeftMargin(lines) yamlContent := strings.Join(lines, "\n") diff --git a/vendor/github.com/aquasecurity/defsec/provider/aws/sam/application.go b/vendor/github.com/aquasecurity/defsec/provider/aws/sam/application.go new file mode 100644 index 00000000..631bf6c7 --- /dev/null +++ b/vendor/github.com/aquasecurity/defsec/provider/aws/sam/application.go @@ -0,0 +1,31 @@ +package sam + +import "github.com/aquasecurity/defsec/types" + +type Application struct { + types.Metadata + LocationPath types.StringValue + Location Location +} + +type Location struct { + types.Metadata + ApplicationID types.StringValue + SemanticVersion types.StringValue +} + +func (a *Application) GetMetadata() *types.Metadata { + return &a.Metadata +} + +func (a *Application) GetRawValue() interface{} { + return nil +} + +func (a *Location) GetMetadata() *types.Metadata { + return &a.Metadata +} + +func (a *Location) GetRawValue() interface{} { + return nil +} diff --git a/vendor/github.com/aquasecurity/defsec/provider/aws/sam/function.go b/vendor/github.com/aquasecurity/defsec/provider/aws/sam/function.go new file mode 100644 index 00000000..bdbf58c7 --- /dev/null +++ b/vendor/github.com/aquasecurity/defsec/provider/aws/sam/function.go @@ -0,0 +1,43 @@ +package sam + +import ( + "github.com/aquasecurity/defsec/provider/aws/iam" + "github.com/aquasecurity/defsec/types" +) + +type Function struct { + types.Metadata + FunctionName types.StringValue + Tracing types.StringValue + ManagedPolicies []types.StringValue + Policies []iam.PolicyDocument +} + +const ( + TracingModePassThrough = "PassThrough" + TracingModeActive = "Active" +) + + +type Permission struct { + types.Metadata + Principal types.StringValue + SourceARN types.StringValue +} + +func (c *Function) GetMetadata() *types.Metadata { + return &c.Metadata +} + +func (c *Function) GetRawValue() interface{} { + return nil +} + + +func (c *Permission) GetMetadata() *types.Metadata { + return &c.Metadata +} + +func (c *Permission) GetRawValue() interface{} { + return nil +} diff --git a/vendor/github.com/aquasecurity/defsec/provider/aws/sam/http_api.go b/vendor/github.com/aquasecurity/defsec/provider/aws/sam/http_api.go new file mode 100644 index 00000000..36706736 --- /dev/null +++ b/vendor/github.com/aquasecurity/defsec/provider/aws/sam/http_api.go @@ -0,0 +1,34 @@ +package sam + +import "github.com/aquasecurity/defsec/types" + +type HttpAPI struct { + types.Metadata + Name types.StringValue + AccessLogging AccessLogging + DefaultRouteSettings RouteSettings + DomainConfiguration DomainConfiguration +} + +type RouteSettings struct { + types.Metadata + LoggingEnabled types.BoolValue + DataTraceEnabled types.BoolValue + DetailedMetricsEnabled types.BoolValue +} + +func (a *HttpAPI) GetMetadata() *types.Metadata { + return &a.Metadata +} + +func (a *HttpAPI) GetRawValue() interface{} { + return nil +} + +func (a *RouteSettings) GetMetadata() *types.Metadata { + return &a.Metadata +} + +func (a *RouteSettings) GetRawValue() interface{} { + return nil +} diff --git a/vendor/github.com/aquasecurity/defsec/provider/aws/sam/sam.go b/vendor/github.com/aquasecurity/defsec/provider/aws/sam/sam.go index ca5516df..ed75777d 100644 --- a/vendor/github.com/aquasecurity/defsec/provider/aws/sam/sam.go +++ b/vendor/github.com/aquasecurity/defsec/provider/aws/sam/sam.go @@ -1,5 +1,10 @@ package sam type SAM struct { - APIs []API + APIs []API + Applications []Application + Functions []Function + HttpAPIs []HttpAPI + SimpleTables []SimpleTable + StateMachines []StateMachine } diff --git a/vendor/github.com/aquasecurity/defsec/provider/aws/sam/state_machine.go b/vendor/github.com/aquasecurity/defsec/provider/aws/sam/state_machine.go new file mode 100644 index 00000000..ee5274b8 --- /dev/null +++ b/vendor/github.com/aquasecurity/defsec/provider/aws/sam/state_machine.go @@ -0,0 +1,49 @@ +package sam + +import ( + "github.com/aquasecurity/defsec/provider/aws/iam" + "github.com/aquasecurity/defsec/types" +) + +type StateMachine struct { + types.Metadata + Name types.StringValue + LoggingConfiguration LoggingConfiguration + ManagedPolicies []types.StringValue + Policies []iam.PolicyDocument + Tracing TracingConfiguration +} + +type LoggingConfiguration struct { + types.Metadata + LoggingEnabled types.BoolValue +} + +type TracingConfiguration struct { + types.Metadata + Enabled types.BoolValue +} + +func (a *StateMachine) GetMetadata() *types.Metadata { + return &a.Metadata +} + +func (a *StateMachine) GetRawValue() interface{} { + return nil +} + +func (a *LoggingConfiguration) GetMetadata() *types.Metadata { + return &a.Metadata +} + +func (a *LoggingConfiguration) GetRawValue() interface{} { + return nil +} + +func (a *TracingConfiguration) GetMetadata() *types.Metadata { + return &a.Metadata +} + +func (a *TracingConfiguration) GetRawValue() interface{} { + return nil +} diff --git a/vendor/github.com/aquasecurity/defsec/provider/aws/sam/table.go b/vendor/github.com/aquasecurity/defsec/provider/aws/sam/table.go new file mode 100644 index 00000000..7d429c14 --- /dev/null +++ b/vendor/github.com/aquasecurity/defsec/provider/aws/sam/table.go @@ -0,0 +1,32 @@ +package sam + +import "github.com/aquasecurity/defsec/types" + +type SimpleTable struct { + types.Metadata + TableName types.StringValue + SSESpecification SSESpecification +} + +type SSESpecification struct { + types.Metadata + + Enabled types.BoolValue + KMSMasterKeyID types.StringValue +} + +func (a *SimpleTable) GetMetadata() *types.Metadata { + return &a.Metadata +} + +func (a *SimpleTable) GetRawValue() interface{} { + return nil +} + +func (a *SSESpecification) GetMetadata() *types.Metadata { + return &a.Metadata +} + +func (a *SSESpecification) GetRawValue() interface{} { + return nil +} diff --git a/vendor/github.com/aquasecurity/defsec/rules/aws/iam/no_policy_wildcards.go b/vendor/github.com/aquasecurity/defsec/rules/aws/iam/no_policy_wildcards.go index 13dd209a..f7f0093c 100644 --- a/vendor/github.com/aquasecurity/defsec/rules/aws/iam/no_policy_wildcards.go +++ b/vendor/github.com/aquasecurity/defsec/rules/aws/iam/no_policy_wildcards.go @@ -66,6 +66,9 @@ func checkStatement(document iam.PolicyDocument, statement iam.PolicyDocumentSta } for _, resource := range statement.Resource { if strings.Contains(resource, "*") && !iam.IsWildcardAllowed(statement.Action...) { + if strings.HasSuffix(resource, "/*") && strings.HasPrefix(resource, "arn:aws:s3") { + continue + } results.Add( "IAM policy document uses wildcarded resource for sensitive action(s).", document, diff --git a/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_access_logging.go b/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_api_access_logging.go similarity index 83% rename from vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_access_logging.go rename to vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_api_access_logging.go index 71b12dfa..b4f0d48e 100644 --- a/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_access_logging.go +++ b/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_api_access_logging.go @@ -7,18 +7,18 @@ import ( "github.com/aquasecurity/defsec/state" ) -var CheckEnableAccessLogging = rules.Register( +var CheckEnableApiAccessLogging = rules.Register( rules.Rule{ AVDID: "AVD-AWS-0113", Provider: provider.AWSProvider, Service: "sam", - ShortCode: "enable-access-logging", + ShortCode: "enable-api-access-logging", Summary: "SAM API stages for V1 and V2 should have access logging enabled", Impact: "Logging provides vital information about access and usage", Resolution: "Enable logging for API Gateway stages", Explanation: `API Gateway stages should have access log settings block configured to track all access to a particular stage. This should be applied to both v1 and v2 gateway stages.`, Links: []string{ - "https://docs.aws.amazon.com/apigateway/latest/developerguide/set-up-logging.html", + "https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-api.html#sam-api-accesslogsetting", }, Severity: severity.Medium, }, diff --git a/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_tracing.go b/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_api_tracing.go similarity index 77% rename from vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_tracing.go rename to vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_api_tracing.go index a32bb3c0..8d2edfad 100644 --- a/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_tracing.go +++ b/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_api_tracing.go @@ -7,22 +7,24 @@ import ( "github.com/aquasecurity/defsec/state" ) -var CheckEnableTracing = rules.Register( +var CheckEnableApiTracing = rules.Register( rules.Rule{ AVDID: "AVD-AWS-0111", Provider: provider.AWSProvider, Service: "sam", - ShortCode: "enable-tracing", + ShortCode: "enable-api-tracing", Summary: "SAM API must have X-Ray tracing enabled", Impact: "Without full tracing enabled it is difficult to trace the flow of logs", Resolution: "Enable tracing", Explanation: `X-Ray tracing enables end-to-end debugging and analysis of all API Gateway HTTP requests.`, - Links: []string{}, + Links: []string{ + "https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-api.html#sam-api-tracingenabled", + }, Severity: severity.Low, }, func(s *state.State) (results rules.Results) { for _, api := range s.AWS.SAM.APIs { - if !api.IsManaged(){ + if !api.IsManaged() { continue } diff --git a/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_cache_encryption.go b/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_cache_encryption.go index 0551013f..e77e06be 100644 --- a/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_cache_encryption.go +++ b/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_cache_encryption.go @@ -7,17 +7,19 @@ import ( "github.com/aquasecurity/defsec/state" ) -var CheckEnableCacheEncryption = rules.Register( +var CheckEnableApiCacheEncryption = rules.Register( rules.Rule{ AVDID: "AVD-AWS-0110", Provider: provider.AWSProvider, Service: "sam", - ShortCode: "enable-cache-encryption", + ShortCode: "enable-api-cache-encryption", Summary: "SAM API must have data cache enabled", Impact: "Data stored in the cache that is unencrypted may be vulnerable to compromise", Resolution: "Enable cache encryption", Explanation: `Method cache encryption ensures that any sensitive data in the cache is not vulnerable to compromise in the event of interception`, - Links: []string{}, + Links: []string{ + "https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-apigateway-stage-methodsetting.html#cfn-apigateway-stage-methodsetting-cachedataencrypted", + }, Severity: severity.Medium, }, func(s *state.State) (results rules.Results) { diff --git a/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_function_tracing.go b/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_function_tracing.go new file mode 100644 index 00000000..38e43f95 --- /dev/null +++ b/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_function_tracing.go @@ -0,0 +1,44 @@ +package sam + +import ( + "github.com/aquasecurity/defsec/provider" + "github.com/aquasecurity/defsec/provider/aws/sam" + "github.com/aquasecurity/defsec/rules" + "github.com/aquasecurity/defsec/severity" + "github.com/aquasecurity/defsec/state" +) + +var CheckEnableFunctionTracing = rules.Register( + rules.Rule{ + AVDID: "AVD-AWS-0113", + Provider: provider.AWSProvider, + Service: "sam", + ShortCode: "enable-function-tracing", + Summary: "SAM Function must have X-Ray tracing enabled", + Impact: "Without full tracing enabled it is difficult to trace the flow of logs", + Resolution: "Enable tracing", + Explanation: `X-Ray tracing enables end-to-end debugging and analysis of the function.`, + Links: []string{ + "https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html#sam-function-tracing", + }, + Severity: severity.Low, + }, + func(s *state.State) (results rules.Results) { + for _, function := range s.AWS.SAM.Functions { + if !function.IsManaged() { + continue + } + + if function.Tracing.NotEqualTo(sam.TracingModeActive) { + results.Add( + "X-Ray tracing is not enabled,", + &function, + function.Tracing, + ) + } else { + results.AddPassed(&function) + } + } + return + }, +) diff --git a/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_http_api_access_logging.go b/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_http_api_access_logging.go new file mode 100644 index 00000000..08d7334f --- /dev/null +++ b/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_http_api_access_logging.go @@ -0,0 +1,44 @@ +package sam + +import ( + "github.com/aquasecurity/defsec/provider" + "github.com/aquasecurity/defsec/rules" + "github.com/aquasecurity/defsec/severity" + "github.com/aquasecurity/defsec/state" +) + +var CheckEnableHttpApiAccessLogging = rules.Register( + rules.Rule{ + AVDID: "AVD-AWS-0116", + Provider: provider.AWSProvider, + Service: "sam", + ShortCode: "enable-http-api-access-logging", + Summary: "SAM HTTP API stages for V1 and V2 should have access logging enabled", + Impact: "Logging provides vital information about access and usage", + Resolution: "Enable logging for API Gateway stages", + Explanation: `API Gateway stages should have access log settings block configured to track all access to a particular stage. This should be applied to both v1 and v2 gateway stages.`, + Links: []string{ + "https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-httpapi.html#sam-httpapi-accesslogsettings", + }, + Severity: severity.Medium, + }, + func(s *state.State) (results rules.Results) { + for _, api := range s.AWS.SAM.HttpAPIs { + if !api.IsManaged() { + continue + } + + if api.AccessLogging.CloudwatchLogGroupARN.IsEmpty() { + results.Add( + "Access logging is not configured.", + &api, + api.AccessLogging.CloudwatchLogGroupARN, + ) + } else { + results.AddPassed(&api) + } + } + + return + }, +) diff --git a/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_state_machine_logging.go b/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_state_machine_logging.go new file mode 100644 index 00000000..e94545c6 --- /dev/null +++ b/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_state_machine_logging.go @@ -0,0 +1,43 @@ +package sam + +import ( + "github.com/aquasecurity/defsec/provider" + "github.com/aquasecurity/defsec/rules" + "github.com/aquasecurity/defsec/severity" + "github.com/aquasecurity/defsec/state" +) + +var CheckEnableStateMachineLogging = rules.Register( + rules.Rule{ + AVDID: "AVD-AWS-0119", + Provider: provider.AWSProvider, + Service: "sam", + ShortCode: "enable-state-machine-logging", + Summary: "SAM State machine must have logging enabled", + Impact: "Without logging enabled it is difficult to identify suspicious activity", + Resolution: "Enable logging", + Explanation: `Logging enables end-to-end debugging and analysis of all state machine activities.`, + Links: []string{ + "https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-statemachine.html#sam-statemachine-logging", + }, + Severity: severity.Low, + }, + func(s *state.State) (results rules.Results) { + for _, stateMachine := range s.AWS.SAM.StateMachines { + if !stateMachine.IsManaged() { + continue + } + + if stateMachine.LoggingConfiguration.LoggingEnabled.IsFalse() { + results.Add( + "Logging is not enabled,", + &stateMachine, + stateMachine.LoggingConfiguration.LoggingEnabled, + ) + } else { + results.AddPassed(&stateMachine) + } + } + return + }, +) diff --git a/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_state_machine_tracing.go b/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_state_machine_tracing.go new file mode 100644 index 00000000..1a351470 --- /dev/null +++ b/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_state_machine_tracing.go @@ -0,0 +1,43 @@ +package sam + +import ( + "github.com/aquasecurity/defsec/provider" + "github.com/aquasecurity/defsec/rules" + "github.com/aquasecurity/defsec/severity" + "github.com/aquasecurity/defsec/state" +) + +var CheckEnableStateMachineTracing = rules.Register( + rules.Rule{ + AVDID: "AVD-AWS-0117", + Provider: provider.AWSProvider, + Service: "sam", + ShortCode: "enable-state-machine-tracing", + Summary: "SAM State machine must have X-Ray tracing enabled", + Impact: "Without full tracing enabled it is difficult to trace the flow of logs", + Resolution: "Enable tracing", + Explanation: `X-Ray tracing enables end-to-end debugging and analysis of all state machine activities.`, + Links: []string{ + "https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-statemachine.html#sam-statemachine-tracing", + }, + Severity: severity.Low, + }, + func(s *state.State) (results rules.Results) { + for _, stateMachine := range s.AWS.SAM.StateMachines { + if !stateMachine.IsManaged() { + continue + } + + if stateMachine.Tracing.Enabled.IsFalse() { + results.Add( + "X-Ray tracing is not enabled,", + &stateMachine, + stateMachine.Tracing.Enabled, + ) + } else { + results.AddPassed(&stateMachine) + } + } + return + }, +) diff --git a/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_table_encryption.go b/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_table_encryption.go new file mode 100644 index 00000000..b73cbad6 --- /dev/null +++ b/vendor/github.com/aquasecurity/defsec/rules/aws/sam/enable_table_encryption.go @@ -0,0 +1,39 @@ +package sam + +import ( + "github.com/aquasecurity/defsec/provider" + "github.com/aquasecurity/defsec/rules" + "github.com/aquasecurity/defsec/severity" + "github.com/aquasecurity/defsec/state" +) + +var CheckEnableTableEncryption = rules.Register( + rules.Rule{ + AVDID: "AVD-AWS-0121", + Provider: provider.AWSProvider, + Service: "sam", + ShortCode: "enable-table-encryption", + Summary: "SAM Simple table must have server side encryption enabled.", + Impact: "Data stored in the table that is unencrypted may be vulnerable to compromise", + Resolution: "Enable server side encryption", + Explanation: `Encryption should be enabled at all available levels to ensure that data is protected if compromised.`, + Links: []string{ + "https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-simpletable.html#sam-simpletable-ssespecification", + }, + Severity: severity.High, + }, + func(s *state.State) (results rules.Results) { + for _, table := range s.AWS.SAM.SimpleTables { + if table.SSESpecification.Enabled.IsFalse() { + results.Add( + "Domain name is configured with an outdated TLS policy.", + &table, + table.SSESpecification.Enabled, + ) + } else { + results.AddPassed(&table) + } + } + return + }, +) diff --git a/vendor/github.com/aquasecurity/defsec/rules/aws/sam/no_function_policy_wildcards.go b/vendor/github.com/aquasecurity/defsec/rules/aws/sam/no_function_policy_wildcards.go new file mode 100644 index 00000000..1d43e417 --- /dev/null +++ b/vendor/github.com/aquasecurity/defsec/rules/aws/sam/no_function_policy_wildcards.go @@ -0,0 +1,83 @@ +package sam + +import ( + "strings" + + "github.com/aquasecurity/defsec/provider" + "github.com/aquasecurity/defsec/provider/aws/iam" + "github.com/aquasecurity/defsec/rules" + "github.com/aquasecurity/defsec/severity" + "github.com/aquasecurity/defsec/state" +) + +var CheckNoFunctionPolicyWildcards = rules.Register( + rules.Rule{ + AVDID: "AVD-AWS-0114", + Provider: provider.AWSProvider, + Service: "sam", + ShortCode: "no-function-policy-wildcards", + Summary: "Function policies should avoid use of wildcards and instead apply the principle of least privilege", + Impact: "Overly permissive policies may grant access to sensitive resources", + Resolution: "Specify the exact permissions required, and to which resources they should apply instead of using wildcards.", + Explanation: `You should use the principle of least privilege when defining your IAM policies. This means you should specify each exact permission required without using wildcards, as this could cause the granting of access to certain undesired actions, resources and principals.`, + Links: []string{ + "https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html#sam-function-policies", + }, + Severity: severity.High, + }, + func(s *state.State) (results rules.Results) { + + for _, function := range s.AWS.SAM.Functions { + if !function.IsManaged() { + continue + } + + for _, document := range function.Policies { + for _, statement := range document.Statements { + results = checkStatement(document, statement, results) + } + } + } + return + }, +) + +func checkStatement(document iam.PolicyDocument, statement iam.PolicyDocumentStatement, results rules.Results) rules.Results { + if strings.ToLower(statement.Effect) == "deny" { + return results + } + for _, action := range statement.Action { + if strings.Contains(action, "*") { + results.Add( + "Policy document uses a wildcard action.", + document, + ) + } else { + results.AddPassed(&document) + } + } + for _, resource := range statement.Resource { + if strings.Contains(resource, "*") && !iam.IsWildcardAllowed(statement.Action...) { + if strings.HasSuffix(resource, "/*") && strings.HasPrefix(resource, "arn:aws:s3") { + continue + } + results.Add( + "Policy document uses a wildcard resource for sensitive action(s).", + document, + ) + } else { + results.AddPassed(&document) + } + } + for _, principal := range statement.Principal.AWS { + if strings.Contains(principal, "*") { + results.Add( + "Policy document uses a wildcard principal.", + document, + ) + } else { + results.AddPassed(&document) + } + } + return results +} diff --git a/vendor/github.com/aquasecurity/defsec/rules/aws/sam/no_state_machine_policy_wildcards.go b/vendor/github.com/aquasecurity/defsec/rules/aws/sam/no_state_machine_policy_wildcards.go new file mode 100644 index 00000000..63015ff2 --- /dev/null +++ b/vendor/github.com/aquasecurity/defsec/rules/aws/sam/no_state_machine_policy_wildcards.go @@ -0,0 +1,40 @@ +package sam + +import ( + "github.com/aquasecurity/defsec/provider" + "github.com/aquasecurity/defsec/rules" + "github.com/aquasecurity/defsec/severity" + "github.com/aquasecurity/defsec/state" +) + +var CheckNoStateMachinePolicyWildcards = rules.Register( + rules.Rule{ + AVDID: "AVD-AWS-0120", + Provider: provider.AWSProvider, + Service: "sam", + ShortCode: "no-state-machine-policy-wildcards", + Summary: "State machine policies should avoid use of wildcards and instead apply the principle of least privilege", + Impact: "Overly permissive policies may grant access to sensitive resources", + Resolution: "Specify the exact permissions required, and to which resources they should apply instead of using wildcards.", + Explanation: `You should use the principle of least privilege when defining your IAM policies. This means you should specify each exact permission required without using wildcards, as this could cause the granting of access to certain undesired actions, resources and principals.`, + Links: []string{ + "https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-statemachine.html#sam-statemachine-policies", + }, + Severity: severity.High, + }, + func(s *state.State) (results rules.Results) { + + for _, stateMachine := range s.AWS.SAM.StateMachines { + if !stateMachine.IsManaged() { + continue + } + + for _, document := range stateMachine.Policies { + for _, statement := range document.Statements { + results = checkStatement(document, statement, results) + } + } + } + return + }, +) diff --git a/vendor/github.com/aquasecurity/defsec/rules/aws/sam/use_secure_tls_policy.go b/vendor/github.com/aquasecurity/defsec/rules/aws/sam/use_secure_tls_policy.go index a60fb09d..1aa50a86 100644 --- a/vendor/github.com/aquasecurity/defsec/rules/aws/sam/use_secure_tls_policy.go +++ b/vendor/github.com/aquasecurity/defsec/rules/aws/sam/use_secure_tls_policy.go @@ -7,18 +7,18 @@ import ( "github.com/aquasecurity/defsec/state" ) -var CheckUseSecureTlsPolicy = rules.Register( +var CheckApiUseSecureTlsPolicy = rules.Register( rules.Rule{ AVDID: "AVD-AWS-0112", Provider: provider.AWSProvider, Service: "sam", - ShortCode: "use-secure-tls-policy", + ShortCode: "api-use-secure-tls-policy", Summary: "SAM API domain name uses outdated SSL/TLS protocols.", Impact: "Outdated SSL policies increase exposure to known vulnerabilities", Resolution: "Use the most modern TLS/SSL policies available", Explanation: `You should not use outdated/insecure TLS versions for encryption. You should be using TLS v1.2+.`, Links: []string{ - "https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-custom-domain-tls-version.html", + "https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-property-api-domainconfiguration.html#sam-api-domainconfiguration-securitypolicy", }, Severity: severity.High, }, diff --git a/vendor/modules.txt b/vendor/modules.txt index 29ae4ba0..5cf6162b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -20,7 +20,7 @@ github.com/acomagu/bufpipe # github.com/apparentlymart/go-cidr v1.1.0 ## explicit github.com/apparentlymart/go-cidr/cidr -# github.com/aquasecurity/defsec v0.0.38-0.20211202114943-52f01d551cdf +# github.com/aquasecurity/defsec v0.0.39 ## explicit github.com/aquasecurity/defsec/cidr github.com/aquasecurity/defsec/formatters