cfn-nag 0.0.30 → 0.0.31
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 +3 -1
- data/lib/cfn_nag.rb +36 -18
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 56dbe4fbd39baa55a57bf08c76b3ded48d248259
|
4
|
+
data.tar.gz: 8453582e991ff40398cc05a0ebee7ef64d5b4291
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ee486be9d272ed90df3f5137358ecf33c719cec14b21acf2f9a9b6669d94ca9f7f227d0bc3916a8a02e368a519c7d07fa2582f529841e088318ba91f235013fd
|
7
|
+
data.tar.gz: d7394d24c0735afc252ffcd59e8d6dfa3419dc358c0dda691d1cfd6e061e01e1eec575e980967fda4418098c7a70ea734a5fac9a00f90acbd157bee26702f410
|
data/bin/cfn_nag
CHANGED
@@ -7,6 +7,7 @@ opts = Trollop::options do
|
|
7
7
|
opt :input_json_path, 'CloudFormation template to nag on or directory of templates - all *.json and *.template recursively', type: :io, required: true
|
8
8
|
opt :output_format, 'Format of results: [txt, json]', type: :string, default: 'txt'
|
9
9
|
opt :debug, 'Enable debug output', type: :boolean, required: false, default: false
|
10
|
+
opt :rule_directory, 'Extra rule directories', type: :strings, require: false, default: [], multi: true
|
10
11
|
end
|
11
12
|
|
12
13
|
Trollop::die(:output_format,
|
@@ -14,4 +15,5 @@ Trollop::die(:output_format,
|
|
14
15
|
|
15
16
|
CfnNag::configure_logging(opts)
|
16
17
|
exit CfnNag.new.audit(input_json_path: opts[:input_json_path],
|
17
|
-
output_format: opts[:output_format]
|
18
|
+
output_format: opts[:output_format],
|
19
|
+
rule_directories: opts[:rule_directory])
|
data/lib/cfn_nag.rb
CHANGED
@@ -13,6 +13,11 @@ class CfnNag
|
|
13
13
|
def initialize
|
14
14
|
@warning_registry = []
|
15
15
|
@violation_registry = []
|
16
|
+
@custom_rule_registry = [
|
17
|
+
SecurityGroupMissingEgressRule,
|
18
|
+
UserMissingGroupRule,
|
19
|
+
UnencryptedS3PutObjectAllowedRule
|
20
|
+
]
|
16
21
|
end
|
17
22
|
|
18
23
|
def dump_rules
|
@@ -47,16 +52,20 @@ class CfnNag
|
|
47
52
|
end
|
48
53
|
|
49
54
|
def audit(input_json_path:,
|
55
|
+
rule_directories: [],
|
50
56
|
output_format:'txt')
|
57
|
+
validate_extra_rule_directories(rule_directories)
|
51
58
|
|
52
59
|
aggregate_results = audit_results input_json_path: input_json_path,
|
53
|
-
output_format: output_format
|
60
|
+
output_format: output_format,
|
61
|
+
rule_directories: rule_directories.flatten
|
54
62
|
|
55
63
|
aggregate_results.inject(0) { |total_failure_count, results| total_failure_count + results[:file_results][:failure_count] }
|
56
64
|
end
|
57
65
|
|
58
66
|
def audit_results(input_json_path:,
|
59
|
-
output_format:'txt'
|
67
|
+
output_format:'txt',
|
68
|
+
rule_directories: [])
|
60
69
|
|
61
70
|
templates = discover_templates(input_json_path)
|
62
71
|
|
@@ -64,7 +73,8 @@ class CfnNag
|
|
64
73
|
templates.each do |template|
|
65
74
|
aggregate_results << {
|
66
75
|
filename: template,
|
67
|
-
file_results: audit_file(input_json_path: template
|
76
|
+
file_results: audit_file(input_json_path: template,
|
77
|
+
rule_directories: rule_directories)
|
68
78
|
}
|
69
79
|
end
|
70
80
|
|
@@ -85,7 +95,7 @@ class CfnNag
|
|
85
95
|
logger.add_appenders Logging.appenders.stdout
|
86
96
|
end
|
87
97
|
|
88
|
-
def audit_template(input_json:)
|
98
|
+
def audit_template(input_json:, rule_directories: [])
|
89
99
|
@stop_processing = false
|
90
100
|
@violations = []
|
91
101
|
|
@@ -96,7 +106,7 @@ class CfnNag
|
|
96
106
|
@stop_processing = true
|
97
107
|
end
|
98
108
|
|
99
|
-
generic_json_rules
|
109
|
+
generic_json_rules(input_json, rule_directories) unless @stop_processing == true
|
100
110
|
|
101
111
|
custom_rules input_json unless @stop_processing == true
|
102
112
|
|
@@ -108,12 +118,20 @@ class CfnNag
|
|
108
118
|
|
109
119
|
private
|
110
120
|
|
121
|
+
def validate_extra_rule_directories(rule_directories)
|
122
|
+
rule_directories.flatten.each do |rule_directory|
|
123
|
+
fail "Not a real directory #{rule_directory}" unless File.directory? rule_directory
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
|
111
128
|
def render_results(aggregate_results:,output_format:)
|
112
129
|
results_renderer(output_format).new.render(aggregate_results)
|
113
130
|
end
|
114
131
|
|
115
|
-
def audit_file(input_json_path:)
|
116
|
-
audit_template(input_json: IO.read(input_json_path)
|
132
|
+
def audit_file(input_json_path:, rule_directories:)
|
133
|
+
audit_template(input_json: IO.read(input_json_path),
|
134
|
+
rule_directories: rule_directories)
|
117
135
|
end
|
118
136
|
|
119
137
|
def discover_templates(input_json_path)
|
@@ -162,7 +180,7 @@ class CfnNag
|
|
162
180
|
__dir__.start_with? '/uri:classloader'
|
163
181
|
end
|
164
182
|
|
165
|
-
def generic_json_rules(input_json)
|
183
|
+
def generic_json_rules(input_json, rule_directories)
|
166
184
|
unless command? 'jq'
|
167
185
|
fail 'jq executable must be available in PATH'
|
168
186
|
end
|
@@ -170,7 +188,6 @@ class CfnNag
|
|
170
188
|
if jruby_in_a_jar?
|
171
189
|
rules = %w(basic_rules cfn_rules cidr_rules cloudfront_rules ebs_rules iam_policy_rules iam_user_rules lambda_rules loadbalancer_rules port_rules s3_bucket_rules sns_rules sqs_rules)
|
172
190
|
rules = rules.map { |rule| File.join(__dir__, 'json_rules', "#{rule}.rb")[1..-1] }
|
173
|
-
puts "Jruby it is: #{rules}"
|
174
191
|
else
|
175
192
|
rules = Dir[File.join(__dir__, 'json_rules', '*.rb')].sort
|
176
193
|
end
|
@@ -179,21 +196,22 @@ class CfnNag
|
|
179
196
|
@input_json = input_json
|
180
197
|
eval IO.read(rule_file)
|
181
198
|
end
|
199
|
+
|
200
|
+
rule_directories.each do |rule_directory|
|
201
|
+
rules = Dir[File.join(rule_directory, '*.rb')].sort
|
202
|
+
|
203
|
+
rules.each do |rule_file|
|
204
|
+
@input_json = input_json
|
205
|
+
eval IO.read(rule_file)
|
206
|
+
end
|
207
|
+
end
|
182
208
|
end
|
183
209
|
|
184
210
|
def custom_rules(input_json)
|
185
211
|
cfn_model = CfnModel.new.parse(input_json)
|
186
|
-
custom_rule_registry.each do |rule_class|
|
212
|
+
@custom_rule_registry.each do |rule_class|
|
187
213
|
audit_result = rule_class.new.audit(cfn_model)
|
188
214
|
@violations << audit_result unless audit_result.nil?
|
189
215
|
end
|
190
216
|
end
|
191
|
-
|
192
|
-
def custom_rule_registry
|
193
|
-
[
|
194
|
-
SecurityGroupMissingEgressRule,
|
195
|
-
UserMissingGroupRule,
|
196
|
-
UnencryptedS3PutObjectAllowedRule
|
197
|
-
]
|
198
|
-
end
|
199
217
|
end
|
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.0.
|
4
|
+
version: 0.0.31
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- someguy
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-02-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: logging
|