cfn-nag 0.3.10 → 0.3.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/cfn_nag +5 -1
- data/bin/cfn_nag_scan +5 -1
- data/lib/cfn-nag/cfn_nag.rb +6 -2
- data/lib/cfn-nag/custom_rule_loader.rb +72 -2
- data/lib/cfn-nag/jmes_path_evaluator.rb +3 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d28e143a404043d2d72720c13b3185b7fb150846
|
4
|
+
data.tar.gz: 054364ac8afe5ae75fd4d4afdc1920d42fcc8c58
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55346cb4a2298a66d24ed27b5bb151be4a598586e09d925ac998223c6d1a8d4e4886751d02eb8327a93244f454a00ac611c0c8ef9929885258a21677278a405d
|
7
|
+
data.tar.gz: b5b11a2eafdc8d814a3fcbdaad095fbf985980571d67b8b2c9ce861af7efd6edd898030841c8e115aaaa14cfc3d97f8bae980acb63e204ecd94fa06d1db5babe
|
data/bin/cfn_nag
CHANGED
@@ -8,6 +8,8 @@ opts = Trollop::options do
|
|
8
8
|
usage '[options] <cloudformation template path ...>|<cloudformation template in STDIN>'
|
9
9
|
|
10
10
|
opt :debug, 'Enable debug output', type: :boolean, required: false, default: false
|
11
|
+
opt :allow_suppression, 'Allow using Metadata to suppress violations', type: :boolean, required: false, default: true
|
12
|
+
opt :print_suppression, 'Emit suppressions to stderr', type: :boolean, required: false, default: false
|
11
13
|
opt :rule_directory, 'Extra rule directory', type: :io, required: false, default: nil
|
12
14
|
opt :profile_path, 'Path to a profile file', type: :io, required: false, default: nil
|
13
15
|
end
|
@@ -20,7 +22,9 @@ unless opts[:profile_path].nil?
|
|
20
22
|
end
|
21
23
|
|
22
24
|
cfn_nag = CfnNag.new(profile_definition: profile_definition,
|
23
|
-
rule_directory: opts[:rule_directory]
|
25
|
+
rule_directory: opts[:rule_directory],
|
26
|
+
allow_suppression: opts[:allow_suppression],
|
27
|
+
print_suppression: opts[:print_suppression])
|
24
28
|
|
25
29
|
# trollop appears to pop args off of ARGV
|
26
30
|
# ARGF concatenates which we don't want
|
data/bin/cfn_nag_scan
CHANGED
@@ -10,6 +10,8 @@ opts = Trollop::options do
|
|
10
10
|
opt :debug, 'Enable debug output', type: :boolean, required: false, default: false
|
11
11
|
opt :rule_directory, 'Extra rule directory', type: :io, required: false, default: nil
|
12
12
|
opt :profile_path, 'Path to a profile file', type: :io, required: false, default: nil
|
13
|
+
opt :allow_suppression, 'Allow using Metadata to suppress violations', type: :boolean, required: false, default: true
|
14
|
+
opt :print_suppression, 'Emit suppressions to stderr', type: :boolean, required: false, default: false
|
13
15
|
end
|
14
16
|
|
15
17
|
Trollop::die(:output_format,
|
@@ -23,7 +25,9 @@ unless opts[:profile_path].nil?
|
|
23
25
|
end
|
24
26
|
|
25
27
|
cfn_nag = CfnNag.new(profile_definition: profile_definition,
|
26
|
-
rule_directory: opts[:rule_directory]
|
28
|
+
rule_directory: opts[:rule_directory],
|
29
|
+
allow_suppression: opts[:allow_suppression],
|
30
|
+
print_suppression: opts[:print_suppression])
|
27
31
|
|
28
32
|
exit cfn_nag.audit_aggregate_across_files_and_render_results(input_path: opts[:input_path],
|
29
33
|
output_format: opts[:output_format])
|
data/lib/cfn-nag/cfn_nag.rb
CHANGED
@@ -9,9 +9,13 @@ require 'logging'
|
|
9
9
|
|
10
10
|
class CfnNag
|
11
11
|
def initialize(profile_definition: nil,
|
12
|
-
rule_directory: nil
|
12
|
+
rule_directory: nil,
|
13
|
+
allow_suppression: true,
|
14
|
+
print_suppression: false)
|
13
15
|
@rule_directory = rule_directory
|
14
|
-
@custom_rule_loader = CustomRuleLoader.new(rule_directory: rule_directory
|
16
|
+
@custom_rule_loader = CustomRuleLoader.new(rule_directory: rule_directory,
|
17
|
+
allow_suppression: allow_suppression,
|
18
|
+
print_suppression: print_suppression)
|
15
19
|
@profile_definition = profile_definition
|
16
20
|
end
|
17
21
|
|
@@ -9,8 +9,12 @@ require 'cfn-nag/jmes_path_discovery'
|
|
9
9
|
# apply these rules to a CfnModel object
|
10
10
|
#
|
11
11
|
class CustomRuleLoader
|
12
|
-
def initialize(rule_directory: nil
|
12
|
+
def initialize(rule_directory: nil,
|
13
|
+
allow_suppression: true,
|
14
|
+
print_suppression: false)
|
13
15
|
@rule_directory = rule_directory
|
16
|
+
@allow_suppression = allow_suppression
|
17
|
+
@print_suppression = print_suppression
|
14
18
|
validate_extra_rule_directory rule_directory
|
15
19
|
end
|
16
20
|
|
@@ -34,13 +38,19 @@ class CustomRuleLoader
|
|
34
38
|
rule_registry
|
35
39
|
end
|
36
40
|
|
41
|
+
|
37
42
|
def execute_custom_rules(cfn_model)
|
38
43
|
Logging.logger['log'].debug "cfn_model: #{cfn_model}"
|
39
44
|
|
40
45
|
violations = []
|
41
46
|
|
47
|
+
validate_cfn_nag_metadata(cfn_model)
|
48
|
+
|
42
49
|
discover_rule_classes(@rule_directory).each do |rule_class|
|
43
|
-
|
50
|
+
filtered_cfn_model = cfn_model_with_suppressed_resources_removed cfn_model: cfn_model,
|
51
|
+
rule_id: rule_class.new.rule_id,
|
52
|
+
allow_suppression: @allow_suppression
|
53
|
+
audit_result = rule_class.new.audit(filtered_cfn_model)
|
44
54
|
violations << audit_result unless audit_result.nil?
|
45
55
|
end
|
46
56
|
|
@@ -56,6 +66,66 @@ class CustomRuleLoader
|
|
56
66
|
|
57
67
|
private
|
58
68
|
|
69
|
+
def rules_to_suppress(resource)
|
70
|
+
if resource.metadata && resource.metadata['cfn_nag'] && resource.metadata['cfn_nag']['rules_to_suppress']
|
71
|
+
resource.metadata['cfn_nag']['rules_to_suppress']
|
72
|
+
else
|
73
|
+
nil
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def validate_cfn_nag_metadata(cfn_model)
|
78
|
+
mangled_metadatas = []
|
79
|
+
cfn_model.resources.each do |logical_resource_id, resource|
|
80
|
+
resource_rules_to_suppress = rules_to_suppress resource
|
81
|
+
if resource_rules_to_suppress.nil?
|
82
|
+
next
|
83
|
+
else
|
84
|
+
mangled_rules = resource_rules_to_suppress.select do |rule_to_suppress|
|
85
|
+
rule_to_suppress['id'].nil?
|
86
|
+
end
|
87
|
+
unless mangled_rules.empty?
|
88
|
+
mangled_metadatas << [logical_resource_id, mangled_rules]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
mangled_metadatas.each do |mangled_metadata|
|
93
|
+
logical_resource_id = mangled_metadata.first
|
94
|
+
mangled_rules = mangled_metadata[1]
|
95
|
+
|
96
|
+
STDERR.puts "#{logical_resource_id} has missing cfn_nag suppression rule id: #{mangled_rules}"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def suppress_resource?(rules_to_suppress, rule_id, logical_resource_id)
|
101
|
+
found_suppression_rule = rules_to_suppress.find do |rule_to_suppress|
|
102
|
+
next if rule_to_suppress['id'].nil?
|
103
|
+
rule_to_suppress['id'] == rule_id
|
104
|
+
end
|
105
|
+
if found_suppression_rule && @print_suppression
|
106
|
+
STDERR.puts "Suppressing #{rule_id} on #{logical_resource_id} for reason: #{found_suppression_rule['reason']}"
|
107
|
+
end
|
108
|
+
!found_suppression_rule.nil?
|
109
|
+
end
|
110
|
+
|
111
|
+
def cfn_model_with_suppressed_resources_removed(cfn_model:,
|
112
|
+
rule_id:,
|
113
|
+
allow_suppression:)
|
114
|
+
return cfn_model unless allow_suppression
|
115
|
+
|
116
|
+
cfn_model = cfn_model.copy
|
117
|
+
|
118
|
+
cfn_model.resources.delete_if do |logical_resource_id, resource|
|
119
|
+
rules_to_suppress = rules_to_suppress resource
|
120
|
+
if rules_to_suppress.nil?
|
121
|
+
false
|
122
|
+
else
|
123
|
+
suppress_resource?(rules_to_suppress, rule_id, logical_resource_id)
|
124
|
+
end
|
125
|
+
end
|
126
|
+
cfn_model
|
127
|
+
end
|
128
|
+
|
59
129
|
def validate_extra_rule_directory(rule_directory)
|
60
130
|
unless rule_directory.nil?
|
61
131
|
fail "Not a real directory #{rule_directory}" unless File.directory? rule_directory
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cfn-nag
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Kascic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-11-
|
11
|
+
date: 2017-11-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: logging
|
@@ -44,14 +44,14 @@ dependencies:
|
|
44
44
|
requirements:
|
45
45
|
- - '='
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0.1.
|
47
|
+
version: 0.1.11
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - '='
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0.1.
|
54
|
+
version: 0.1.11
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: jmespath
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|