cfn-nag 0.3.43 → 0.3.44
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/cfn-nag/cfn_nag.rb +19 -21
- data/lib/cfn-nag/custom_rule_loader.rb +39 -29
- data/lib/cfn-nag/custom_rules/CloudFormationAuthenticationRule.rb +1 -0
- data/lib/cfn-nag/custom_rules/CloudFrontDistributionAccessLoggingRule.rb +1 -0
- data/lib/cfn-nag/custom_rules/base.rb +6 -7
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d94e81c63455c6eda830af691fecf9da6bbec732818c879fd77b24341443b834
|
4
|
+
data.tar.gz: 170e6a4f324a2b58e19f38e9c36ab3c27c31daf2144ea0d94630de3ce661438f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 735a3bdfbbff963559a7eacabea92a28fe6f5451bf9aabadb05b6e94921d98d369b3c37d2d747a060b111e1886d19fed4461cdde1001d250a12e271b53a8197a
|
7
|
+
data.tar.gz: 2b8412e8c7d1aae3371d177045ddb14e2c7c71ecc312d7fa910dbdee592853abd2e995bc538f481f0f02cd19c971c2194e01bd99afcb20c988c8a58260725018
|
data/lib/cfn-nag/cfn_nag.rb
CHANGED
@@ -7,6 +7,7 @@ require_relative 'result_view/json_results'
|
|
7
7
|
require 'cfn-model'
|
8
8
|
require 'logging'
|
9
9
|
|
10
|
+
# Top-level CfnNag class for running profiles
|
10
11
|
class CfnNag
|
11
12
|
def initialize(profile_definition: nil,
|
12
13
|
rule_directory: nil,
|
@@ -42,6 +43,8 @@ class CfnNag
|
|
42
43
|
end
|
43
44
|
end
|
44
45
|
|
46
|
+
# rubocop:disable Metrics/MethodLength
|
47
|
+
|
45
48
|
##
|
46
49
|
# Given a file or directory path, return aggregate results
|
47
50
|
#
|
@@ -59,6 +62,9 @@ class CfnNag
|
|
59
62
|
end
|
60
63
|
aggregate_results
|
61
64
|
end
|
65
|
+
# rubocop:enable Metrics/MethodLength
|
66
|
+
|
67
|
+
# rubocop:disable Metrics/MethodLength
|
62
68
|
|
63
69
|
##
|
64
70
|
# Given cloudformation json/yml, run all the rules against it
|
@@ -69,29 +75,21 @@ class CfnNag
|
|
69
75
|
# Return a hash with failure count
|
70
76
|
#
|
71
77
|
def audit(cloudformation_string:, parameter_values_string: nil)
|
72
|
-
stop_processing = false
|
73
78
|
violations = []
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
violations
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
violations += @custom_rule_loader.execute_custom_rules(cfn_model)
|
87
|
-
violations = filter_violations_by_profile violations
|
88
|
-
end
|
89
|
-
|
90
|
-
{
|
91
|
-
failure_count: Violation.count_failures(violations),
|
92
|
-
violations: violations
|
93
|
-
}
|
79
|
+
cfn_model = CfnParser.new.parse cloudformation_string,
|
80
|
+
parameter_values_string
|
81
|
+
violations += @custom_rule_loader.execute_custom_rules(cfn_model)
|
82
|
+
violations = filter_violations_by_profile violations
|
83
|
+
{ failure_count: Violation.count_failures(violations),
|
84
|
+
violations: violations }
|
85
|
+
rescue Psych::SyntaxError, ParserError => parser_error
|
86
|
+
violations << Violation.new(id: 'FATAL',
|
87
|
+
type: Violation::FAILING_VIOLATION,
|
88
|
+
message: parser_error.to_s)
|
89
|
+
{ failure_count: Violation.count_failures(violations),
|
90
|
+
violations: violations }
|
94
91
|
end
|
92
|
+
# rubocop:enable Metrics/MethodLength
|
95
93
|
|
96
94
|
def self.configure_logging(opts)
|
97
95
|
logger = Logging.logger['log']
|
@@ -24,10 +24,8 @@ class CustomRuleLoader
|
|
24
24
|
rule_registry = RuleRegistry.new
|
25
25
|
|
26
26
|
discover_rule_classes(@rule_directory).each do |rule_class|
|
27
|
-
|
28
|
-
|
29
|
-
type: rule.rule_type,
|
30
|
-
message: rule.rule_text)
|
27
|
+
rule_registry
|
28
|
+
.definition(**rule_registry_from_rule_class(rule_class))
|
31
29
|
end
|
32
30
|
|
33
31
|
discover_jmespath_filenames(@rule_directory).each do |jmespath_file|
|
@@ -47,6 +45,33 @@ class CustomRuleLoader
|
|
47
45
|
|
48
46
|
validate_cfn_nag_metadata(cfn_model)
|
49
47
|
|
48
|
+
filter_rule_classes cfn_model, violations
|
49
|
+
|
50
|
+
filter_jmespath_filenames cfn_model, violations
|
51
|
+
|
52
|
+
violations
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def rule_registry_from_rule_class(rule_class)
|
58
|
+
rule = rule_class.new
|
59
|
+
{ id: rule.rule_id,
|
60
|
+
type: rule.rule_type,
|
61
|
+
message: rule.rule_text }
|
62
|
+
end
|
63
|
+
|
64
|
+
def filter_jmespath_filenames(cfn_model, violations)
|
65
|
+
discover_jmespath_filenames(@rule_directory).each do |jmespath_file|
|
66
|
+
evaluator = JmesPathEvaluator.new cfn_model
|
67
|
+
evaluator.instance_eval do
|
68
|
+
eval IO.read jmespath_file
|
69
|
+
end
|
70
|
+
violations += evaluator.violations
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def filter_rule_classes(cfn_model, violations)
|
50
75
|
discover_rule_classes(@rule_directory).each do |rule_class|
|
51
76
|
begin
|
52
77
|
filtered_cfn_model = cfn_model_with_suppressed_resources_removed \
|
@@ -55,26 +80,12 @@ class CustomRuleLoader
|
|
55
80
|
audit_result = rule_class.new.audit(filtered_cfn_model)
|
56
81
|
violations << audit_result unless audit_result.nil?
|
57
82
|
rescue Exception => exception
|
58
|
-
|
59
|
-
|
60
|
-
else
|
61
|
-
raise exception
|
62
|
-
end
|
83
|
+
raise exception unless @isolate_custom_rule_exceptions
|
84
|
+
STDERR.puts exception
|
63
85
|
end
|
64
86
|
end
|
65
|
-
|
66
|
-
discover_jmespath_filenames(@rule_directory).each do |jmespath_file|
|
67
|
-
evaluator = JmesPathEvaluator.new cfn_model
|
68
|
-
evaluator.instance_eval do
|
69
|
-
eval IO.read jmespath_file
|
70
|
-
end
|
71
|
-
violations += evaluator.violations
|
72
|
-
end
|
73
|
-
violations
|
74
87
|
end
|
75
88
|
|
76
|
-
private
|
77
|
-
|
78
89
|
def rules_to_suppress(resource)
|
79
90
|
if resource.metadata &&
|
80
91
|
resource.metadata['cfn_nag'] &&
|
@@ -84,19 +95,18 @@ class CustomRuleLoader
|
|
84
95
|
end
|
85
96
|
end
|
86
97
|
|
98
|
+
# XXX given mangled_metadatas is never used or returned,
|
99
|
+
# STDERR emit can be moved to unless block
|
87
100
|
def validate_cfn_nag_metadata(cfn_model)
|
88
101
|
mangled_metadatas = []
|
89
102
|
cfn_model.resources.each do |logical_resource_id, resource|
|
90
103
|
resource_rules_to_suppress = rules_to_suppress resource
|
91
|
-
if resource_rules_to_suppress.nil?
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
unless mangled_rules.empty?
|
98
|
-
mangled_metadatas << [logical_resource_id, mangled_rules]
|
99
|
-
end
|
104
|
+
next if resource_rules_to_suppress.nil?
|
105
|
+
mangled_rules = resource_rules_to_suppress.select do |rule_to_suppress|
|
106
|
+
rule_to_suppress['id'].nil?
|
107
|
+
end
|
108
|
+
unless mangled_rules.empty?
|
109
|
+
mangled_metadatas << [logical_resource_id, mangled_rules]
|
100
110
|
end
|
101
111
|
end
|
102
112
|
mangled_metadatas.each do |mangled_metadata|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'cfn-nag/violation'
|
2
2
|
|
3
|
+
# Base class all Rules should subclass
|
3
4
|
class BaseRule
|
4
5
|
##
|
5
6
|
# Returns a collection of logical resource ids
|
@@ -14,12 +15,10 @@ class BaseRule
|
|
14
15
|
#
|
15
16
|
def audit(cfn_model)
|
16
17
|
logical_resource_ids = audit_impl(cfn_model)
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
logical_resource_ids: logical_resource_ids)
|
23
|
-
end
|
18
|
+
return if logical_resource_ids.empty?
|
19
|
+
Violation.new(id: rule_id,
|
20
|
+
type: rule_type,
|
21
|
+
message: rule_text,
|
22
|
+
logical_resource_ids: logical_resource_ids)
|
24
23
|
end
|
25
24
|
end
|