cfn-nag 0.3.67 → 0.3.68

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ca2c6915b65ea17382453ae70f489848805320dcea810216e3830065242cf921
4
- data.tar.gz: 2ad82b8452806b72055b58a984edd30573df020e4ca7b97802c21e000235e4c6
3
+ metadata.gz: ffbdd25dd16e216af5280c00d56987c2236765b6e0467c3c35fc3167333802f0
4
+ data.tar.gz: 1a7d2fbeaca398861088d3f138ebd2b1bc89e03f85aa58af230353fed6790012
5
5
  SHA512:
6
- metadata.gz: aba6c9c12ede913365cb6dfd63aff3d517b8720e0c9f5e9f409757b5b9172ece6efa3d55613cad96070e9f753e4d80879fd876ed3d4468fc65497b9a1e2d7dc1
7
- data.tar.gz: 1442d1e3d10b86a85339970c7e95c711a8c0c61f486461b85f01a2b6d696ebb4fd850a57f6a0be5df17567431a452d00e080af9549b31e8d0e6ff472ed9f9f25
6
+ metadata.gz: 93235ea544b753874959e97ad5e72c776b40ce5687adbb3fcdf8f9f45390e9280e049f72d0974c9d8116883454f740270ec39deac382e3da20d24842e37886d4
7
+ data.tar.gz: ad62b96251d1a425007cae5cfdab6244880920489fc552136386cf7ebeed84187b5eeca21d3de19be2ff3365d553d6bb95eda268ff522e229f88ca01bf14713e
data/bin/cfn_nag CHANGED
@@ -8,7 +8,12 @@ require 'json'
8
8
  require 'rubygems/specification'
9
9
 
10
10
  opts = Trollop.options do
11
- usage '[options] <cloudformation template path ...>|<cloudformation template in STDIN>'
11
+ options_message = '[options] <cloudformation template path ...>|' \
12
+ '<cloudformation template in STDIN>'
13
+ custom_rule_exceptions_message = 'Isolate custom rule exceptions - ' \
14
+ 'just emit the exception without stack ' \
15
+ ' trace and keep chugging'
16
+ usage options_message
12
17
  version Gem::Specification.find_by_name('cfn-nag').version
13
18
 
14
19
  opt :debug,
@@ -42,7 +47,7 @@ opts = Trollop.options do
42
47
  required: false,
43
48
  default: nil
44
49
  opt :isolate_custom_rule_exceptions,
45
- 'Isolate custom rule exceptions - just emit the exception without stack trace and keep chugging',
50
+ custom_rule_exceptions_message,
46
51
  type: :boolean,
47
52
  required: false,
48
53
  default: false
@@ -60,12 +65,13 @@ unless opts[:parameter_values_path].nil?
60
65
  parameter_values_string = IO.read(opts[:parameter_values_path])
61
66
  end
62
67
 
63
- cfn_nag = CfnNag.new(profile_definition: profile_definition,
64
- rule_directory: opts[:rule_directory],
65
- allow_suppression: opts[:allow_suppression],
66
- print_suppression: opts[:print_suppression],
67
- isolate_custom_rule_exceptions:
68
- opts[:isolate_custom_rule_exceptions])
68
+ cfn_nag = CfnNag.new(
69
+ profile_definition: profile_definition,
70
+ rule_directory: opts[:rule_directory],
71
+ allow_suppression: opts[:allow_suppression],
72
+ print_suppression: opts[:print_suppression],
73
+ isolate_custom_rule_exceptions: opts[:isolate_custom_rule_exceptions]
74
+ )
69
75
 
70
76
  total_failure_count = 0
71
77
  until ARGF.closed? || ARGF.eof?
data/bin/cfn_nag_scan CHANGED
@@ -10,8 +10,20 @@ require 'rubygems/specification'
10
10
  opts = Trollop.options do
11
11
  version Gem::Specification.find_by_name('cfn-nag').version
12
12
 
13
+ input_path_message = 'CloudFormation template to nag on or directory of ' \
14
+ 'templates. Default is all *.json, *.yaml, *.yml ' \
15
+ 'and *.template recursively, but can be constrained ' \
16
+ 'by --template-pattern'
17
+
18
+ custom_rule_exceptions_message = 'Isolate custom rule exceptions - just ' \
19
+ 'emit the exception without stack trace ' \
20
+ 'and keep chugging'
21
+
22
+ template_pattern_message = 'Within the --input-path, match files to scan ' \
23
+ 'against this regular expression'
24
+
13
25
  opt :input_path,
14
- 'CloudFormation template to nag on or directory of templates. Default is all *.json, *.yaml, *.yml and *.template recursively, but can be constrained by --template-pattern',
26
+ input_path_message,
15
27
  type: :io,
16
28
  required: true
17
29
  opt :output_format,
@@ -49,12 +61,12 @@ opts = Trollop.options do
49
61
  required: false,
50
62
  default: false
51
63
  opt :isolate_custom_rule_exceptions,
52
- 'Isolate custom rule exceptions - just emit the exception without stack trace and keep chugging',
64
+ custom_rule_exceptions_message,
53
65
  type: :boolean,
54
66
  required: false,
55
67
  default: false
56
68
  opt :template_pattern,
57
- 'Within the --input-path, match files to scan against this regular expression',
69
+ template_pattern_message,
58
70
  type: :string,
59
71
  required: false,
60
72
  default: '..*\.json|..*\.yaml|..*\.yml|..*\.template'
@@ -72,14 +84,17 @@ unless opts[:profile_path].nil?
72
84
  profile_definition = IO.read(opts[:profile_path])
73
85
  end
74
86
 
75
- cfn_nag = CfnNag.new(profile_definition: profile_definition,
76
- rule_directory: opts[:rule_directory],
77
- allow_suppression: opts[:allow_suppression],
78
- print_suppression: opts[:print_suppression],
79
- isolate_custom_rule_exceptions: opts[:isolate_custom_rule_exceptions])
87
+ cfn_nag = CfnNag.new(
88
+ profile_definition: profile_definition,
89
+ rule_directory: opts[:rule_directory],
90
+ allow_suppression: opts[:allow_suppression],
91
+ print_suppression: opts[:print_suppression],
92
+ isolate_custom_rule_exceptions: opts[:isolate_custom_rule_exceptions]
93
+ )
80
94
 
81
95
  exit cfn_nag.audit_aggregate_across_files_and_render_results(
82
- input_path: opts[:input_path], output_format: opts[:output_format],
96
+ input_path: opts[:input_path],
97
+ output_format: opts[:output_format],
83
98
  parameter_values_path: opts[:parameter_values_path],
84
99
  template_pattern: opts[:template_pattern]
85
100
  )
@@ -66,19 +66,6 @@ class CfnNag
66
66
  aggregate_results
67
67
  end
68
68
 
69
- def audit_result(violations)
70
- {
71
- failure_count: Violation.count_failures(violations),
72
- violations: violations
73
- }
74
- end
75
-
76
- def fatal_violation(message)
77
- Violation.new(id: 'FATAL',
78
- type: Violation::FAILING_VIOLATION,
79
- message: message)
80
- end
81
-
82
69
  ##
83
70
  # Given cloudformation json/yml, run all the rules against it
84
71
  #
@@ -118,6 +105,19 @@ class CfnNag
118
105
 
119
106
  private
120
107
 
108
+ def audit_result(violations)
109
+ {
110
+ failure_count: Violation.count_failures(violations),
111
+ violations: violations
112
+ }
113
+ end
114
+
115
+ def fatal_violation(message)
116
+ Violation.new(id: 'FATAL',
117
+ type: Violation::FAILING_VIOLATION,
118
+ message: message)
119
+ end
120
+
121
121
  def filter_violations_by_profile(violations)
122
122
  profile = nil
123
123
  unless @profile_definition.nil?
@@ -78,9 +78,11 @@ class CustomRuleLoader
78
78
  def filter_rule_classes(cfn_model, violations)
79
79
  discover_rule_classes(@rule_directory).each do |rule_class|
80
80
  begin
81
- filtered_cfn_model = cfn_model_with_suppressed_resources_removed cfn_model: cfn_model,
82
- rule_id: rule_class.new.rule_id,
83
- allow_suppression: @allow_suppression
81
+ filtered_cfn_model = cfn_model_with_suppressed_resources_removed(
82
+ cfn_model: cfn_model,
83
+ rule_id: rule_class.new.rule_id,
84
+ allow_suppression: @allow_suppression
85
+ )
84
86
  audit_result = rule_class.new.audit(filtered_cfn_model)
85
87
  violations << audit_result unless audit_result.nil?
86
88
  rescue Exception => exception
@@ -122,7 +124,8 @@ class CustomRuleLoader
122
124
  logical_resource_id = mangled_metadata.first
123
125
  mangled_rules = mangled_metadata[1]
124
126
 
125
- STDERR.puts "#{logical_resource_id} has missing cfn_nag suppression rule id: #{mangled_rules}"
127
+ STDERR.puts "#{logical_resource_id} has missing cfn_nag suppression " \
128
+ "rule id: #{mangled_rules}"
126
129
  end
127
130
  end
128
131
 
@@ -132,7 +135,9 @@ class CustomRuleLoader
132
135
  rule_to_suppress['id'] == rule_id
133
136
  end
134
137
  if found_suppression_rule && @print_suppression
135
- STDERR.puts "Suppressing #{rule_id} on #{logical_resource_id} for reason: #{found_suppression_rule['reason']}"
138
+ message = "Suppressing #{rule_id} on #{logical_resource_id} for " \
139
+ "reason: #{found_suppression_rule['reason']}"
140
+ STDERR.puts message
136
141
  end
137
142
  !found_suppression_rule.nil?
138
143
  end
@@ -5,7 +5,8 @@ require_relative 'base'
5
5
 
6
6
  class LambdaPermissionInvokeFunctionActionRule < BaseRule
7
7
  def rule_text
8
- 'Lambda permission beside InvokeFunction might not be what you want? Not sure!?'
8
+ 'Lambda permission beside InvokeFunction might not be what you want? ' \
9
+ 'Not sure!?'
9
10
  end
10
11
 
11
12
  def rule_type
@@ -17,10 +18,11 @@ class LambdaPermissionInvokeFunctionActionRule < BaseRule
17
18
  end
18
19
 
19
20
  def audit_impl(cfn_model)
20
- violating_lambdas = cfn_model.resources_by_type('AWS::Lambda::Permission').select do |lambda_permission|
21
+ lambda_permissions = cfn_model.resources_by_type('AWS::Lambda::Permission')
22
+ violating_lambda_permissions = lambda_permissions.select do |lambda_permission|
21
23
  lambda_permission.action != 'lambda:InvokeFunction'
22
24
  end
23
25
 
24
- violating_lambdas.map(&:logical_resource_id)
26
+ violating_lambda_permissions.map(&:logical_resource_id)
25
27
  end
26
28
  end
@@ -18,10 +18,11 @@ class LambdaPermissionWildcardPrincipalRule < BaseRule
18
18
  end
19
19
 
20
20
  def audit_impl(cfn_model)
21
- violating_lambdas = cfn_model.resources_by_type('AWS::Lambda::Permission').select do |lambda_permission|
21
+ lambda_permissions = cfn_model.resources_by_type('AWS::Lambda::Permission')
22
+ violating_lambda_permissions = lambda_permissions.select do |lambda_permission|
22
23
  LambdaPrincipal.wildcard? lambda_permission.principal
23
24
  end
24
25
 
25
- violating_lambdas.map(&:logical_resource_id)
26
+ violating_lambda_permissions.map(&:logical_resource_id)
26
27
  end
27
28
  end
@@ -5,7 +5,8 @@ require_relative 'base'
5
5
 
6
6
  class RDSInstanceMasterUserPasswordRule < BaseRule
7
7
  def rule_text
8
- 'RDS instance master user password must be Ref to NoEcho Parameter. Default credentials are not recommended'
8
+ 'RDS instance master user password must be Ref to NoEcho Parameter. ' \
9
+ 'Default credentials are not recommended'
9
10
  end
10
11
 
11
12
  def rule_type
@@ -16,15 +17,18 @@ class RDSInstanceMasterUserPasswordRule < BaseRule
16
17
  'F23'
17
18
  end
18
19
 
19
- # one word of warning... if somebody applies parameter values via JSON.... this will compare that....
20
- # probably shouldn't be doing that though - if it's NoEcho there's a good reason
20
+ # one word of warning... if somebody applies parameter values via JSON....
21
+ # this will compare that....
22
+ # probably shouldn't be doing that though if it's NoEcho there's a good reason
21
23
  # bother checking synthesized_value? that would be the indicator.....
22
24
  def audit_impl(cfn_model)
23
- violating_rdsinstances = cfn_model.resources_by_type('AWS::RDS::DBInstance').select do |instance|
25
+ rds_dbinstances = cfn_model.resources_by_type('AWS::RDS::DBInstance')
26
+ violating_rdsinstances = rds_dbinstances.select do |instance|
24
27
  if instance.masterUserPassword.nil?
25
28
  false
26
29
  else
27
- !references_no_echo_parameter_without_default?(cfn_model, instance.masterUserPassword)
30
+ !no_echo_parameter_without_default?(cfn_model,
31
+ instance.masterUserPassword)
28
32
  end
29
33
  end
30
34
 
@@ -37,7 +41,7 @@ class RDSInstanceMasterUserPasswordRule < BaseRule
37
41
  string.to_s.casecmp('true').zero?
38
42
  end
39
43
 
40
- def references_no_echo_parameter_without_default?(cfn_model, master_user_password)
44
+ def no_echo_parameter_without_default?(cfn_model, master_user_password)
41
45
  # i feel like i've written this mess somewhere before
42
46
  if master_user_password.is_a? Hash
43
47
  if master_user_password.key? 'Ref'
@@ -6,7 +6,8 @@ require_relative 'base'
6
6
  # cfn_nag rules related to RDS Instance master username
7
7
  class RDSInstanceMasterUsernameRule < BaseRule
8
8
  def rule_text
9
- 'RDS instance master username must be Ref to NoEcho Parameter. Default credentials are not recommended'
9
+ 'RDS instance master username must be Ref to NoEcho Parameter. Default ' \
10
+ 'credentials are not recommended'
10
11
  end
11
12
 
12
13
  def rule_type
@@ -17,7 +17,9 @@ class RDSInstancePubliclyAccessibleRule < BaseRule
17
17
  end
18
18
 
19
19
  def audit_impl(cfn_model)
20
- violating_rdsinstances = cfn_model.resources_by_type('AWS::RDS::DBInstance').select do |instance|
20
+ rds_dbinstances = cfn_model.resources_by_type('AWS::RDS::DBInstance')
21
+
22
+ violating_rdsinstances = rds_dbinstances.select do |instance|
21
23
  instance.publiclyAccessible.nil? || instance.publiclyAccessible.to_s.casecmp('true').zero?
22
24
  end
23
25
 
@@ -17,12 +17,10 @@ class S3BucketPublicReadWriteAclRule < BaseRule
17
17
  end
18
18
 
19
19
  def audit_impl(cfn_model)
20
- logical_resource_ids = []
21
-
22
- cfn_model.resources_by_type('AWS::S3::Bucket').each do |bucket|
23
- logical_resource_ids << bucket.logical_resource_id if bucket.accessControl == 'PublicReadWrite'
20
+ violating_buckets = cfn_model.resources_by_type('AWS::S3::Bucket').select do |bucket|
21
+ bucket.accessControl == 'PublicReadWrite'
24
22
  end
25
23
 
26
- logical_resource_ids
24
+ violating_buckets.map(&:logical_resource_id)
27
25
  end
28
26
  end
@@ -20,21 +20,21 @@ class SecurityGroupEgressOpenToWorldRule < BaseRule
20
20
  end
21
21
 
22
22
  ##
23
- # This will behave slightly different than the legacy jq based rule which was targeted against inline ingress only
23
+ # This will behave slightly different than the legacy jq based rule which was
24
+ # targeted against inline ingress only
24
25
  def audit_impl(cfn_model)
25
- logical_resource_ids = []
26
- cfn_model.security_groups.each do |security_group|
26
+ violating_security_groups = cfn_model.security_groups.select do |security_group|
27
27
  violating_egresses = security_group.egresses.select do |egress|
28
28
  ip4_open?(egress) || ip6_open?(egress)
29
29
  end
30
30
 
31
- logical_resource_ids << security_group.logical_resource_id unless violating_egresses.empty?
31
+ !violating_egresses.empty?
32
32
  end
33
33
 
34
34
  violating_egresses = cfn_model.standalone_egress.select do |standalone_egress|
35
35
  ip4_open?(standalone_egress) || ip6_open?(standalone_egress)
36
36
  end
37
37
 
38
- logical_resource_ids + violating_egresses.map(&:logical_resource_id)
38
+ violating_security_groups.map(&:logical_resource_id) + violating_egresses.map(&:logical_resource_id)
39
39
  end
40
40
  end
@@ -17,21 +17,21 @@ class SecurityGroupEgressPortRangeRule < BaseRule
17
17
  end
18
18
 
19
19
  ##
20
- # This will behave slightly different than the legacy jq based rule which was targeted against inline ingress only
20
+ # This will behave slightly different than the legacy jq based rule which was
21
+ # targeted against inline ingress only
21
22
  def audit_impl(cfn_model)
22
- logical_resource_ids = []
23
- cfn_model.security_groups.each do |security_group|
23
+ violating_security_groups = cfn_model.security_groups.select do |security_group|
24
24
  violating_egresses = security_group.egresses.select do |egress|
25
25
  egress.fromPort != egress.toPort
26
26
  end
27
27
 
28
- logical_resource_ids << security_group.logical_resource_id unless violating_egresses.empty?
28
+ !violating_egresses.empty?
29
29
  end
30
30
 
31
31
  violating_egresses = cfn_model.standalone_egress.select do |standalone_egress|
32
32
  standalone_egress.fromPort != standalone_egress.toPort
33
33
  end
34
34
 
35
- logical_resource_ids + violating_egresses.map(&:logical_resource_id)
35
+ violating_security_groups.map(&:logical_resource_id) + violating_egresses.map(&:logical_resource_id)
36
36
  end
37
37
  end
@@ -20,21 +20,21 @@ class SecurityGroupIngressCidrNon32Rule < BaseRule
20
20
  end
21
21
 
22
22
  ##
23
- # This will behave slightly different than the legacy jq based rule which was targeted against inline ingress only
23
+ # This will behave slightly different than the legacy jq based rule which was
24
+ # targeted against inline ingress only
24
25
  def audit_impl(cfn_model)
25
- logical_resource_ids = []
26
- cfn_model.security_groups.each do |security_group|
26
+ violating_security_groups = cfn_model.security_groups.select do |security_group|
27
27
  violating_ingresses = security_group.ingresses.select do |ingress|
28
28
  ip4_cidr_range?(ingress) || ip6_cidr_range?(ingress)
29
29
  end
30
30
 
31
- logical_resource_ids << security_group.logical_resource_id unless violating_ingresses.empty?
31
+ !violating_ingresses.empty?
32
32
  end
33
33
 
34
34
  violating_ingresses = cfn_model.standalone_ingress.select do |standalone_ingress|
35
35
  ip4_cidr_range?(standalone_ingress) || ip6_cidr_range?(standalone_ingress)
36
36
  end
37
37
 
38
- logical_resource_ids + violating_ingresses.map(&:logical_resource_id)
38
+ violating_security_groups.map(&:logical_resource_id) + violating_ingresses.map(&:logical_resource_id)
39
39
  end
40
40
  end
@@ -8,7 +8,8 @@ class SecurityGroupIngressOpenToWorldRule < BaseRule
8
8
  include IpAddr
9
9
 
10
10
  def rule_text
11
- 'Security Groups found with cidr open to world on ingress. This should never be true on instance. Permissible on ELB'
11
+ 'Security Groups found with cidr open to world on ingress. This should ' \
12
+ 'never be true on instance. Permissible on ELB'
12
13
  end
13
14
 
14
15
  def rule_type
@@ -23,19 +24,18 @@ class SecurityGroupIngressOpenToWorldRule < BaseRule
23
24
  # This will behave slightly different than the legacy jq based rule
24
25
  # which was targeted against inline ingress only
25
26
  def audit_impl(cfn_model)
26
- logical_resource_ids = []
27
- cfn_model.security_groups.each do |security_group|
27
+ violating_security_groups = cfn_model.security_groups.select do |security_group|
28
28
  violating_ingresses = security_group.ingresses.select do |ingress|
29
29
  ip4_open?(ingress) || ip6_open?(ingress)
30
30
  end
31
31
 
32
- logical_resource_ids << security_group.logical_resource_id unless violating_ingresses.empty?
32
+ !violating_ingresses.empty?
33
33
  end
34
34
 
35
35
  violating_ingresses = cfn_model.standalone_ingress.select do |standalone_ingress|
36
36
  ip4_open?(standalone_ingress) || ip6_open?(standalone_ingress)
37
37
  end
38
38
 
39
- logical_resource_ids + violating_ingresses.map(&:logical_resource_id)
39
+ violating_security_groups.map(&:logical_resource_id) + violating_ingresses.map(&:logical_resource_id)
40
40
  end
41
41
  end
@@ -5,7 +5,8 @@ require_relative 'base'
5
5
 
6
6
  class SecurityGroupIngressPortRangeRule < BaseRule
7
7
  def rule_text
8
- 'Security Groups found ingress with port range instead of just a single port'
8
+ 'Security Groups found ingress with port range instead of just a single ' \
9
+ 'port'
9
10
  end
10
11
 
11
12
  def rule_type
@@ -17,21 +18,21 @@ class SecurityGroupIngressPortRangeRule < BaseRule
17
18
  end
18
19
 
19
20
  ##
20
- # This will behave slightly different than the legacy jq based rule which was targeted against inline ingress only
21
+ # This will behave slightly different than the legacy jq based rule which was
22
+ # targeted against inline ingress only
21
23
  def audit_impl(cfn_model)
22
- logical_resource_ids = []
23
- cfn_model.security_groups.each do |security_group|
24
+ violating_security_groups = cfn_model.security_groups.select do |security_group|
24
25
  violating_ingresses = security_group.ingresses.select do |ingress|
25
26
  ingress.fromPort != ingress.toPort
26
27
  end
27
28
 
28
- logical_resource_ids << security_group.logical_resource_id unless violating_ingresses.empty?
29
+ !violating_ingresses.empty?
29
30
  end
30
31
 
31
32
  violating_ingresses = cfn_model.standalone_ingress.select do |standalone_ingress|
32
33
  standalone_ingress.fromPort != standalone_ingress.toPort
33
34
  end
34
35
 
35
- logical_resource_ids + violating_ingresses.map(&:logical_resource_id)
36
+ violating_security_groups.map(&:logical_resource_id) + violating_ingresses.map(&:logical_resource_id)
36
37
  end
37
38
  end
@@ -5,7 +5,8 @@ require_relative 'base'
5
5
 
6
6
  class SecurityGroupMissingEgressRule < BaseRule
7
7
  def rule_text
8
- 'Missing egress rule means all traffic is allowed outbound. Make this explicit if it is desired configuration'
8
+ 'Missing egress rule means all traffic is allowed outbound. Make this ' \
9
+ 'explicit if it is desired configuration'
9
10
  end
10
11
 
11
12
  def rule_type
@@ -17,11 +18,10 @@ class SecurityGroupMissingEgressRule < BaseRule
17
18
  end
18
19
 
19
20
  def audit_impl(cfn_model)
20
- logical_resource_ids = []
21
- cfn_model.security_groups.each do |security_group|
22
- logical_resource_ids << security_group.logical_resource_id if security_group.egresses.empty?
21
+ violating_security_groups = cfn_model.security_groups.select do |security_group|
22
+ security_group.egresses.empty?
23
23
  end
24
24
 
25
- logical_resource_ids
25
+ violating_security_groups.map(&:logical_resource_id)
26
26
  end
27
27
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cfn-nag
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.67
4
+ version: 0.3.68
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eric Kascic
@@ -193,7 +193,6 @@ files:
193
193
  - lib/cfn-nag/custom_rules/WafWebAclDefaultActionRule.rb
194
194
  - lib/cfn-nag/custom_rules/WorkspacesWorkspaceEncryptionRule.rb
195
195
  - lib/cfn-nag/custom_rules/base.rb
196
- - lib/cfn-nag/custom_rules/unencrypted_s3_put_allowed.rb
197
196
  - lib/cfn-nag/ip_addr.rb
198
197
  - lib/cfn-nag/jmes_path_discovery.rb
199
198
  - lib/cfn-nag/jmes_path_evaluator.rb
@@ -1,60 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # require 'cfn-nag/violation'
4
- # require 'model/action_parser'
5
- #
6
- # class UnencryptedS3PutObjectAllowedRule
7
- #
8
- # def rule_text
9
- # 'It appears that the S3 Bucket Policy allows s3:PutObject without server-side encryption'
10
- # end
11
- #
12
- # def rule_type
13
- # Violation::WARNING
14
- # end
15
- #
16
- # def rule_id
17
- # 'W1000'
18
- # end
19
- #
20
- # def audit(cfn_model)
21
- # logical_resource_ids = []
22
- # cfn_model.bucket_policies.each do |bucket_policy|
23
- # found_statement = bucket_policy.statements.find do |statement|
24
- # blocks_put_object_without_encryption(statement)
25
- # end
26
- # if found_statement.nil?
27
- # logical_resource_ids << bucket_policy.logical_resource_id
28
- # end
29
- # end
30
- #
31
- # if logical_resource_ids.size > 0
32
- # Violation.new(id: rule_id,
33
- # type: rule_type,
34
- # message: rule_text,
35
- # logical_resource_ids: logical_resource_ids)
36
- # else
37
- # nil
38
- # end
39
- # end
40
- #
41
- # private
42
- #
43
- # def blocks_put_object_without_encryption(statement)
44
- # encryption_condition = {
45
- # 'StringNotEquals' => {
46
- # 's3:x-amz-server-side-encryption' => 'AES256'
47
- # }
48
- # }
49
- #
50
- # # this isn't quite complete. parsing the Resource field can be tricky
51
- # # looking for a trailing wildcard will likely be right most of the time
52
- # # but there are a lot of string manipulations to confuse things so...
53
- # # just warn when we can't find at least the Deny+encryption - they may have an
54
- # # incomplete Deny (for encryption) and that will slip through
55
- # statement['Effect'] == 'Deny' and
56
- # ActionParser.new.include?(actual_action: statement['Action'], action_to_look_for: 's3:PutObject') and
57
- # S3BucketPolicy::condition_includes?(statement, encryption_condition) and
58
- # statement['Principal'] == '*'
59
- # end
60
- # end