cfn-nag 0.0.44 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/cfn_nag +27 -11
- data/bin/cfn_nag_rules +5 -4
- data/bin/cfn_nag_scan +29 -0
- data/lib/cfn-nag.rb +3 -0
- data/lib/cfn-nag/cfn_nag.rb +115 -0
- data/lib/cfn-nag/custom_rule_loader.rb +72 -0
- data/lib/cfn-nag/custom_rules/CloudFormationAuthenticationRule.rb +28 -0
- data/lib/cfn-nag/custom_rules/CloudFrontDistributionAccessLoggingRule.rb +24 -0
- data/lib/cfn-nag/custom_rules/EbsVolumeHasSseRule.rb +24 -0
- data/lib/cfn-nag/custom_rules/ElasticLoadBalancerAccessLoggingRule.rb +24 -0
- data/lib/cfn-nag/custom_rules/IamManagedPolicyNotActionRule.rb +25 -0
- data/lib/cfn-nag/custom_rules/IamManagedPolicyNotResourceRule.rb +25 -0
- data/lib/cfn-nag/custom_rules/IamManagedPolicyWildcardActionRule.rb +25 -0
- data/lib/cfn-nag/custom_rules/IamManagedPolicyWildcardResourceRule.rb +25 -0
- data/lib/cfn-nag/custom_rules/IamPolicyNotActionRule.rb +25 -0
- data/lib/cfn-nag/custom_rules/IamPolicyNotResourceRule.rb +25 -0
- data/lib/cfn-nag/custom_rules/IamPolicyWildcardActionRule.rb +25 -0
- data/lib/cfn-nag/custom_rules/IamPolicyWildcardResourceRule.rb +25 -0
- data/lib/cfn-nag/custom_rules/IamRoleNotActionOnPermissionsPolicyRule.rb +28 -0
- data/lib/cfn-nag/custom_rules/IamRoleNotActionOnTrustPolicyRule.rb +25 -0
- data/lib/cfn-nag/custom_rules/IamRoleNotPrincipalOnTrustPolicyRule.rb +25 -0
- data/lib/cfn-nag/custom_rules/IamRoleNotResourceOnPermissionsPolicyRule.rb +28 -0
- data/lib/cfn-nag/custom_rules/IamRoleWildcardActionOnPermissionsPolicyRule.rb +28 -0
- data/lib/cfn-nag/custom_rules/IamRoleWildcardActionOnTrustPolicyRule.rb +27 -0
- data/lib/cfn-nag/custom_rules/IamRoleWildcardResourceOnPermissionsPolicyRule.rb +28 -0
- data/lib/cfn-nag/custom_rules/LambdaPermissionInvokeFunctionActionRule.rb +24 -0
- data/lib/cfn-nag/custom_rules/LambdaPermissionWildcardPrincipalRule.rb +24 -0
- data/lib/cfn-nag/custom_rules/ManagedPolicyOnUserRule.rb +24 -0
- data/lib/cfn-nag/custom_rules/PolicyOnUserRule.rb +24 -0
- data/lib/cfn-nag/custom_rules/S3BucketPolicyNotActionRule.rb +25 -0
- data/lib/cfn-nag/custom_rules/S3BucketPolicyNotPrincipalRule.rb +25 -0
- data/lib/cfn-nag/custom_rules/S3BucketPolicyWildcardActionRule.rb +30 -0
- data/lib/cfn-nag/custom_rules/S3BucketPolicyWildcardPrincipalRule.rb +29 -0
- data/lib/cfn-nag/custom_rules/S3BucketPublicReadAclRule.rb +29 -0
- data/lib/cfn-nag/custom_rules/S3BucketPublicReadWriteAclRule.rb +29 -0
- data/lib/cfn-nag/custom_rules/SecurityGroupEgressOpenToWorldRule.rb +39 -0
- data/lib/cfn-nag/custom_rules/SecurityGroupEgressPortRangeRule.rb +38 -0
- data/lib/cfn-nag/custom_rules/SecurityGroupIngressCidrNon32Rule.rb +40 -0
- data/lib/cfn-nag/custom_rules/SecurityGroupIngressOpenToWorldRule.rb +39 -0
- data/lib/cfn-nag/custom_rules/SecurityGroupIngressPortRangeRule.rb +38 -0
- data/lib/{custom_rules/security_group_missing_egress.rb → cfn-nag/custom_rules/SecurityGroupMissingEgressRule.rb} +6 -12
- data/lib/cfn-nag/custom_rules/SnsTopicPolicyNotActionRule.rb +25 -0
- data/lib/cfn-nag/custom_rules/SnsTopicPolicyNotPrincipalRule.rb +26 -0
- data/lib/cfn-nag/custom_rules/SnsTopicPolicyWildcardPrincipalRule.rb +29 -0
- data/lib/cfn-nag/custom_rules/SqsQueuePolicyNotActionRule.rb +25 -0
- data/lib/cfn-nag/custom_rules/SqsQueuePolicyNotPrincipalRule.rb +25 -0
- data/lib/cfn-nag/custom_rules/SqsQueuePolicyWildcardActionRule.rb +30 -0
- data/lib/cfn-nag/custom_rules/SqsQueuePolicyWildcardPrincipalRule.rb +29 -0
- data/lib/cfn-nag/custom_rules/UserHasInlinePolicyRule.rb +25 -0
- data/lib/cfn-nag/custom_rules/UserMissingGroupRule.rb +28 -0
- data/lib/cfn-nag/custom_rules/WafWebAclDefaultActionRule.rb +34 -0
- data/lib/cfn-nag/custom_rules/base.rb +28 -0
- data/lib/cfn-nag/custom_rules/unencrypted_s3_put_allowed.rb +58 -0
- data/lib/{profile.rb → cfn-nag/profile.rb} +0 -1
- data/lib/{profile_loader.rb → cfn-nag/profile_loader.rb} +2 -2
- data/lib/{result_view → cfn-nag/result_view}/json_results.rb +0 -0
- data/lib/{result_view → cfn-nag/result_view}/rules_view.rb +0 -0
- data/lib/{result_view → cfn-nag/result_view}/simple_stdout_results.rb +5 -12
- data/lib/cfn-nag/rule_definition.rb +36 -0
- data/lib/cfn-nag/rule_dumper.rb +23 -0
- data/lib/cfn-nag/rule_registry.rb +43 -0
- data/lib/cfn-nag/template_discovery.rb +24 -0
- data/lib/cfn-nag/violation.rb +58 -0
- metadata +79 -36
- data/lib/cfn_nag.rb +0 -219
- data/lib/custom_rule_loader.rb +0 -64
- data/lib/custom_rules/unencrypted_s3_put_allowed.rb +0 -58
- data/lib/custom_rules/user_missing_group.rb +0 -34
- data/lib/json_rules/basic_rules.rb +0 -49
- data/lib/json_rules/cfn_rules.rb +0 -4
- data/lib/json_rules/cidr_rules.rb +0 -77
- data/lib/json_rules/cloudfront_rules.rb +0 -4
- data/lib/json_rules/ebs_rules.rb +0 -4
- data/lib/json_rules/iam_policy_rules.rb +0 -153
- data/lib/json_rules/iam_user_rules.rb +0 -15
- data/lib/json_rules/lambda_rules.rb +0 -9
- data/lib/json_rules/loadbalancer_rules.rb +0 -9
- data/lib/json_rules/port_rules.rb +0 -33
- data/lib/json_rules/s3_bucket_rules.rb +0 -51
- data/lib/json_rules/sns_rules.rb +0 -29
- data/lib/json_rules/sqs_rules.rb +0 -25
- data/lib/model/action_parser.rb +0 -27
- data/lib/model/cfn_model.rb +0 -182
- data/lib/model/iam_user_parser.rb +0 -34
- data/lib/model/parser_registry.rb +0 -31
- data/lib/model/s3_bucket_policy.rb +0 -25
- data/lib/model/s3_bucket_policy_parser.rb +0 -28
- data/lib/model/security_group_parser.rb +0 -59
- data/lib/rule.rb +0 -208
- data/lib/rule_registry.rb +0 -45
- data/lib/violation.rb +0 -41
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'cfn-nag/violation'
|
2
|
+
require_relative 'base'
|
3
|
+
|
4
|
+
class PolicyOnUserRule < BaseRule
|
5
|
+
def rule_text
|
6
|
+
'IAM policy should not apply directly to users. Should be on group'
|
7
|
+
end
|
8
|
+
|
9
|
+
def rule_type
|
10
|
+
Violation::FAILING_VIOLATION
|
11
|
+
end
|
12
|
+
|
13
|
+
def rule_id
|
14
|
+
'F11'
|
15
|
+
end
|
16
|
+
|
17
|
+
def audit_impl(cfn_model)
|
18
|
+
violating_policies = cfn_model.resources_by_type('AWS::IAM::Policy').select do |policy|
|
19
|
+
policy.users.size > 0
|
20
|
+
end
|
21
|
+
|
22
|
+
violating_policies.map { |violating_user| violating_user.logical_resource_id }
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'cfn-nag/violation'
|
2
|
+
require_relative 'base'
|
3
|
+
|
4
|
+
class S3BucketPolicyNotActionRule < BaseRule
|
5
|
+
|
6
|
+
def rule_text
|
7
|
+
'S3 Bucket policy should not allow Allow+NotAction'
|
8
|
+
end
|
9
|
+
|
10
|
+
def rule_type
|
11
|
+
Violation::WARNING
|
12
|
+
end
|
13
|
+
|
14
|
+
def rule_id
|
15
|
+
'W20'
|
16
|
+
end
|
17
|
+
|
18
|
+
def audit_impl(cfn_model)
|
19
|
+
violating_policies = cfn_model.resources_by_type('AWS::S3::BucketPolicy').select do |policy|
|
20
|
+
!policy.policyDocument.allows_not_action.empty?
|
21
|
+
end
|
22
|
+
|
23
|
+
violating_policies.map { |policy| policy.logical_resource_id }
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'cfn-nag/violation'
|
2
|
+
require_relative 'base'
|
3
|
+
|
4
|
+
class S3BucketPolicyNotPrincipalRule < BaseRule
|
5
|
+
|
6
|
+
def rule_text
|
7
|
+
'S3 Bucket policy should not allow Allow+NotPrincipal'
|
8
|
+
end
|
9
|
+
|
10
|
+
def rule_type
|
11
|
+
Violation::FAILING_VIOLATION
|
12
|
+
end
|
13
|
+
|
14
|
+
def rule_id
|
15
|
+
'F9'
|
16
|
+
end
|
17
|
+
|
18
|
+
def audit_impl(cfn_model)
|
19
|
+
violating_policies = cfn_model.resources_by_type('AWS::S3::BucketPolicy').select do |policy|
|
20
|
+
!policy.policyDocument.allows_not_principal.empty?
|
21
|
+
end
|
22
|
+
|
23
|
+
violating_policies.map { |policy| policy.logical_resource_id }
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'cfn-nag/violation'
|
2
|
+
require_relative 'base'
|
3
|
+
|
4
|
+
class S3BucketPolicyWildcardActionRule < BaseRule
|
5
|
+
|
6
|
+
def rule_text
|
7
|
+
'S3 Bucket policy should not allow * action'
|
8
|
+
end
|
9
|
+
|
10
|
+
def rule_type
|
11
|
+
Violation::FAILING_VIOLATION
|
12
|
+
end
|
13
|
+
|
14
|
+
def rule_id
|
15
|
+
'F15'
|
16
|
+
end
|
17
|
+
|
18
|
+
def audit_impl(cfn_model)
|
19
|
+
logical_resource_ids = []
|
20
|
+
|
21
|
+
cfn_model.resources_by_type('AWS::S3::BucketPolicy').each do |bucket_policy|
|
22
|
+
|
23
|
+
if !bucket_policy.policyDocument.wildcard_allowed_actions.empty?
|
24
|
+
logical_resource_ids << bucket_policy.logical_resource_id
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
logical_resource_ids
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'cfn-nag/violation'
|
2
|
+
require_relative 'base'
|
3
|
+
|
4
|
+
class S3BucketPolicyWildcardPrincipalRule < BaseRule
|
5
|
+
|
6
|
+
def rule_text
|
7
|
+
'S3 Bucket policy should not allow * principal'
|
8
|
+
end
|
9
|
+
|
10
|
+
def rule_type
|
11
|
+
Violation::FAILING_VIOLATION
|
12
|
+
end
|
13
|
+
|
14
|
+
def rule_id
|
15
|
+
'F16'
|
16
|
+
end
|
17
|
+
|
18
|
+
def audit_impl(cfn_model)
|
19
|
+
logical_resource_ids = []
|
20
|
+
|
21
|
+
cfn_model.resources_by_type('AWS::S3::BucketPolicy').each do |topic_policy|
|
22
|
+
if !topic_policy.policyDocument.wildcard_allowed_principals.empty?
|
23
|
+
logical_resource_ids << topic_policy.logical_resource_id
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
logical_resource_ids
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'cfn-nag/violation'
|
2
|
+
require_relative 'base'
|
3
|
+
|
4
|
+
class S3BucketPublicReadAclRule < BaseRule
|
5
|
+
|
6
|
+
def rule_text
|
7
|
+
'S3 Bucket likely should not have a public read acl'
|
8
|
+
end
|
9
|
+
|
10
|
+
def rule_type
|
11
|
+
Violation::WARNING
|
12
|
+
end
|
13
|
+
|
14
|
+
def rule_id
|
15
|
+
'W31'
|
16
|
+
end
|
17
|
+
|
18
|
+
def audit_impl(cfn_model)
|
19
|
+
logical_resource_ids = []
|
20
|
+
|
21
|
+
cfn_model.resources_by_type('AWS::S3::Bucket').each do |bucket|
|
22
|
+
if bucket.accessControl == 'PublicRead'
|
23
|
+
logical_resource_ids << bucket.logical_resource_id
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
logical_resource_ids
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'cfn-nag/violation'
|
2
|
+
require_relative 'base'
|
3
|
+
|
4
|
+
class S3BucketPublicReadWriteAclRule < BaseRule
|
5
|
+
|
6
|
+
def rule_text
|
7
|
+
'S3 Bucket should not have a public read-write acl'
|
8
|
+
end
|
9
|
+
|
10
|
+
def rule_type
|
11
|
+
Violation::FAILING_VIOLATION
|
12
|
+
end
|
13
|
+
|
14
|
+
def rule_id
|
15
|
+
'F14'
|
16
|
+
end
|
17
|
+
|
18
|
+
def audit_impl(cfn_model)
|
19
|
+
logical_resource_ids = []
|
20
|
+
|
21
|
+
cfn_model.resources_by_type('AWS::S3::Bucket').each do |bucket|
|
22
|
+
if bucket.accessControl == 'PublicReadWrite'
|
23
|
+
logical_resource_ids << bucket.logical_resource_id
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
logical_resource_ids
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'cfn-nag/violation'
|
2
|
+
require_relative 'base'
|
3
|
+
|
4
|
+
class SecurityGroupEgressOpenToWorldRule < BaseRule
|
5
|
+
|
6
|
+
def rule_text
|
7
|
+
'Security Groups found with cidr open to world on egress'
|
8
|
+
end
|
9
|
+
|
10
|
+
def rule_type
|
11
|
+
Violation::WARNING
|
12
|
+
end
|
13
|
+
|
14
|
+
def rule_id
|
15
|
+
'W5'
|
16
|
+
end
|
17
|
+
|
18
|
+
##
|
19
|
+
# This will behave slightly different than the legacy jq based rule which was targeted against inline ingress only
|
20
|
+
def audit_impl(cfn_model)
|
21
|
+
logical_resource_ids = []
|
22
|
+
cfn_model.security_groups.each do |security_group|
|
23
|
+
violating_egresses = security_group.securityGroupEgress.select do |egress|
|
24
|
+
# only care about literals. if a Hash/Ref not going to chase it down given likely a Parameter with external val
|
25
|
+
egress.cidrIp.is_a?(String) && egress.cidrIp == '0.0.0.0/0'
|
26
|
+
end
|
27
|
+
|
28
|
+
unless violating_egresses.empty?
|
29
|
+
logical_resource_ids << security_group.logical_resource_id
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
violating_egresses = cfn_model.standalone_egress.select do |standalone_egress|
|
34
|
+
standalone_egress.cidrIp.is_a?(String) && standalone_egress.cidrIp == '0.0.0.0/0'
|
35
|
+
end
|
36
|
+
|
37
|
+
logical_resource_ids + violating_egresses.map { |egress| egress.logical_resource_id}
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'cfn-nag/violation'
|
2
|
+
require_relative 'base'
|
3
|
+
|
4
|
+
class SecurityGroupEgressPortRangeRule < BaseRule
|
5
|
+
|
6
|
+
def rule_text
|
7
|
+
'Security Groups found egress with port range instead of just a single port'
|
8
|
+
end
|
9
|
+
|
10
|
+
def rule_type
|
11
|
+
Violation::WARNING
|
12
|
+
end
|
13
|
+
|
14
|
+
def rule_id
|
15
|
+
'W29'
|
16
|
+
end
|
17
|
+
|
18
|
+
##
|
19
|
+
# This will behave slightly different than the legacy jq based rule which was targeted against inline ingress only
|
20
|
+
def audit_impl(cfn_model)
|
21
|
+
logical_resource_ids = []
|
22
|
+
cfn_model.security_groups.each do |security_group|
|
23
|
+
violating_egresses = security_group.securityGroupEgress.select do |egress|
|
24
|
+
egress.fromPort != egress.toPort
|
25
|
+
end
|
26
|
+
|
27
|
+
unless violating_egresses.empty?
|
28
|
+
logical_resource_ids << security_group.logical_resource_id
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
violating_egresses = cfn_model.standalone_egress.select do |standalone_egress|
|
33
|
+
standalone_egress.fromPort != standalone_egress.toPort
|
34
|
+
end
|
35
|
+
|
36
|
+
logical_resource_ids + violating_egresses.map { |egress| egress.logical_resource_id}
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'cfn-nag/violation'
|
2
|
+
require_relative 'base'
|
3
|
+
|
4
|
+
class SecurityGroupIngressCidrNon32Rule < BaseRule
|
5
|
+
|
6
|
+
def rule_text
|
7
|
+
'Security Groups found with ingress cidr that is not /32'
|
8
|
+
end
|
9
|
+
|
10
|
+
def rule_type
|
11
|
+
Violation::WARNING
|
12
|
+
end
|
13
|
+
|
14
|
+
def rule_id
|
15
|
+
'W9'
|
16
|
+
end
|
17
|
+
|
18
|
+
##
|
19
|
+
# This will behave slightly different than the legacy jq based rule which was targeted against inline ingress only
|
20
|
+
def audit_impl(cfn_model)
|
21
|
+
logical_resource_ids = []
|
22
|
+
cfn_model.security_groups.each do |security_group|
|
23
|
+
violating_ingresses = security_group.securityGroupIngress.select do |ingress|
|
24
|
+
# only care about literals. if a Hash/Ref not going to chase it down given likely a Parameter with external val
|
25
|
+
ingress.cidrIp.is_a?(String) && !ingress.cidrIp.end_with?('/32')
|
26
|
+
end
|
27
|
+
|
28
|
+
unless violating_ingresses.empty?
|
29
|
+
logical_resource_ids << security_group.logical_resource_id
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
violating_ingresses = cfn_model.standalone_ingress.select do |standalone_ingress|
|
34
|
+
standalone_ingress.cidrIp.is_a?(String) && !standalone_ingress.cidrIp.end_with?('/32')
|
35
|
+
end
|
36
|
+
|
37
|
+
logical_resource_ids + violating_ingresses.map { |ingress| ingress.logical_resource_id}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'cfn-nag/violation'
|
2
|
+
require_relative 'base'
|
3
|
+
|
4
|
+
class SecurityGroupIngressOpenToWorldRule < BaseRule
|
5
|
+
|
6
|
+
def rule_text
|
7
|
+
'Security Groups found with cidr open to world on ingress. This should never be true on instance. Permissible on ELB'
|
8
|
+
end
|
9
|
+
|
10
|
+
def rule_type
|
11
|
+
Violation::WARNING
|
12
|
+
end
|
13
|
+
|
14
|
+
def rule_id
|
15
|
+
'W2'
|
16
|
+
end
|
17
|
+
|
18
|
+
##
|
19
|
+
# This will behave slightly different than the legacy jq based rule which was targeted against inline ingress only
|
20
|
+
def audit_impl(cfn_model)
|
21
|
+
logical_resource_ids = []
|
22
|
+
cfn_model.security_groups.each do |security_group|
|
23
|
+
violating_ingresses = security_group.securityGroupIngress.select do |ingress|
|
24
|
+
# only care about literals. if a Hash/Ref not going to chase it down given likely a Parameter with external val
|
25
|
+
ingress.cidrIp.is_a?(String) && ingress.cidrIp == '0.0.0.0/0'
|
26
|
+
end
|
27
|
+
|
28
|
+
unless violating_ingresses.empty?
|
29
|
+
logical_resource_ids << security_group.logical_resource_id
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
violating_ingresses = cfn_model.standalone_ingress.select do |standalone_ingress|
|
34
|
+
standalone_ingress.cidrIp.is_a?(String) && standalone_ingress.cidrIp == '0.0.0.0/0'
|
35
|
+
end
|
36
|
+
|
37
|
+
logical_resource_ids + violating_ingresses.map { |ingress| ingress.logical_resource_id}
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'cfn-nag/violation'
|
2
|
+
require_relative 'base'
|
3
|
+
|
4
|
+
class SecurityGroupIngressPortRangeRule < BaseRule
|
5
|
+
|
6
|
+
def rule_text
|
7
|
+
'Security Groups found ingress with port range instead of just a single port'
|
8
|
+
end
|
9
|
+
|
10
|
+
def rule_type
|
11
|
+
Violation::WARNING
|
12
|
+
end
|
13
|
+
|
14
|
+
def rule_id
|
15
|
+
'W27'
|
16
|
+
end
|
17
|
+
|
18
|
+
##
|
19
|
+
# This will behave slightly different than the legacy jq based rule which was targeted against inline ingress only
|
20
|
+
def audit_impl(cfn_model)
|
21
|
+
logical_resource_ids = []
|
22
|
+
cfn_model.security_groups.each do |security_group|
|
23
|
+
violating_ingresses = security_group.securityGroupIngress.select do |ingress|
|
24
|
+
ingress.fromPort != ingress.toPort
|
25
|
+
end
|
26
|
+
|
27
|
+
unless violating_ingresses.empty?
|
28
|
+
logical_resource_ids << security_group.logical_resource_id
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
violating_ingresses = cfn_model.standalone_ingress.select do |standalone_ingress|
|
33
|
+
standalone_ingress.fromPort != standalone_ingress.toPort
|
34
|
+
end
|
35
|
+
|
36
|
+
logical_resource_ids + violating_ingresses.map { |ingress| ingress.logical_resource_id}
|
37
|
+
end
|
38
|
+
end
|
@@ -1,6 +1,7 @@
|
|
1
|
-
|
1
|
+
require 'cfn-nag/violation'
|
2
|
+
require_relative 'base'
|
2
3
|
|
3
|
-
class SecurityGroupMissingEgressRule
|
4
|
+
class SecurityGroupMissingEgressRule < BaseRule
|
4
5
|
|
5
6
|
def rule_text
|
6
7
|
'Missing egress rule means all traffic is allowed outbound. Make this explicit if it is desired configuration'
|
@@ -14,21 +15,14 @@ class SecurityGroupMissingEgressRule
|
|
14
15
|
'F1000'
|
15
16
|
end
|
16
17
|
|
17
|
-
def
|
18
|
+
def audit_impl(cfn_model)
|
18
19
|
logical_resource_ids = []
|
19
20
|
cfn_model.security_groups.each do |security_group|
|
20
|
-
if security_group.
|
21
|
+
if security_group.securityGroupEgress.empty?
|
21
22
|
logical_resource_ids << security_group.logical_resource_id
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
25
|
-
|
26
|
-
Violation.new(id: rule_id,
|
27
|
-
type: rule_type,
|
28
|
-
message: rule_text,
|
29
|
-
logical_resource_ids: logical_resource_ids)
|
30
|
-
else
|
31
|
-
nil
|
32
|
-
end
|
26
|
+
logical_resource_ids
|
33
27
|
end
|
34
28
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'cfn-nag/violation'
|
2
|
+
require_relative 'base'
|
3
|
+
|
4
|
+
class SnsTopicPolicyNotActionRule < BaseRule
|
5
|
+
|
6
|
+
def rule_text
|
7
|
+
'SNS Topic policy should not allow Allow+NotAction'
|
8
|
+
end
|
9
|
+
|
10
|
+
def rule_type
|
11
|
+
Violation::WARNING
|
12
|
+
end
|
13
|
+
|
14
|
+
def rule_id
|
15
|
+
'W19'
|
16
|
+
end
|
17
|
+
|
18
|
+
def audit_impl(cfn_model)
|
19
|
+
violating_policies = cfn_model.resources_by_type('AWS::SNS::TopicPolicy').select do |policy|
|
20
|
+
!policy.policyDocument.allows_not_action.empty?
|
21
|
+
end
|
22
|
+
|
23
|
+
violating_policies.map { |policy| policy.logical_resource_id }
|
24
|
+
end
|
25
|
+
end
|