cfn-nag 0.7.15 → 0.8.2
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_rules +3 -3
- data/bin/spcm_scan +1 -1
- data/lib/cfn-nag/base_rule.rb +7 -1
- data/lib/cfn-nag/cfn_nag.rb +16 -20
- data/lib/cfn-nag/cfn_nag_config.rb +3 -3
- data/lib/cfn-nag/cfn_nag_executor.rb +7 -7
- data/lib/cfn-nag/cli_options.rb +19 -8
- data/lib/cfn-nag/custom_rules/AlexaASKSkillAuthenticationConfigurationClientSecretRule.rb +1 -1
- data/lib/cfn-nag/custom_rules/AlexaASKSkillAuthenticationConfigurationRefreshTokenRule.rb +1 -1
- data/lib/cfn-nag/custom_rules/AmazonMQBrokerUsersPasswordRule.rb +1 -1
- data/lib/cfn-nag/custom_rules/AmplifyAppAccessTokenRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/AmplifyAppBasicAuthConfigPasswordRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/AmplifyAppOauthTokenRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/AmplifyBranchBasicAuthConfigPasswordRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/ApiGatewayAccessLoggingRule.rb +1 -1
- data/lib/cfn-nag/custom_rules/ApiGatewayCacheEncryptedRule.rb +1 -1
- data/lib/cfn-nag/custom_rules/ApiGatewayMethodAuthorizationTypeRule.rb +1 -1
- data/lib/cfn-nag/custom_rules/AppStreamDirectoryConfigServiceAccountCredentialsAccountPasswordRule.rb +3 -3
- data/lib/cfn-nag/custom_rules/CodePipelineWebhookAuthenticationConfigurationSecretTokenRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/CognitoIdentityPoolAllowUnauthenticatedIdentitiesRule.rb +1 -1
- data/lib/cfn-nag/custom_rules/DMSEndpointMongoDbSettingsPasswordRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/DMSEndpointPasswordRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/DirectoryServiceMicrosoftADPasswordRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/DirectoryServiceSimpleADPasswordRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/DocDBDBClusterMasterUserPasswordRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/EC2NetworkAclEntryProtocolRule.rb +3 -7
- data/lib/cfn-nag/custom_rules/EKSClusterEncryptionRule.rb +1 -3
- data/lib/cfn-nag/custom_rules/EMRClusterKerberosAttributesADDomainJoinPasswordRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/EMRClusterKerberosAttributesCrossRealmTrustPrincipalPasswordRule.rb +3 -3
- data/lib/cfn-nag/custom_rules/EMRClusterKerberosAttributesKdcAdminPasswordRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/ElastiCacheReplicationGroupAuthTokenRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/GameLiftFleetInboundPortRangeRule.rb +2 -0
- data/lib/cfn-nag/custom_rules/IAMUserLoginProfilePasswordRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/IamUserLoginProfilePasswordResetRule.rb +4 -6
- data/lib/cfn-nag/custom_rules/KMSKeyWildcardPrincipalRule.rb +1 -1
- data/lib/cfn-nag/custom_rules/KinesisFirehoseDeliveryStreamRedshiftDestinationConfigurationPasswordRule.rb +3 -3
- data/lib/cfn-nag/custom_rules/KinesisFirehoseDeliveryStreamSplunkDestinationConfigurationHECTokenRule.rb +3 -3
- data/lib/cfn-nag/custom_rules/KinesisStreamStreamEncryptionRule.rb +3 -5
- data/lib/cfn-nag/custom_rules/LambdaPermissionEventSourceTokenRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/LambdaPermissionInvokeFunctionActionRule.rb +1 -1
- data/lib/cfn-nag/custom_rules/ManagedBlockchainMemberMemberFabricConfigurationAdminPasswordRule.rb +4 -7
- data/lib/cfn-nag/custom_rules/OpsWorksAppAppSourcePasswordRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/OpsWorksAppSslConfigurationPrivateKeyRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/OpsWorksStackCustomCookbooksSourcePasswordRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/OpsWorksStackRdsDbInstancesDbPasswordRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/PinpointAPNSChannelPrivateKeyRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/PinpointAPNSChannelTokenKeyRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/PinpointAPNSSandboxChannelPrivateKeyRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/PinpointAPNSSandboxChannelTokenKeyRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/PinpointAPNSVoipChannelPrivateKeyRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/PinpointAPNSVoipChannelTokenKeyRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/PinpointAPNSVoipSandboxChannelPrivateKeyRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/PinpointAPNSVoipSandboxChannelTokenKeyRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/RDSDBClusterMasterUserPasswordRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/RDSDBInstanceMasterUserPasswordRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/RDSDBInstanceMasterUsernameRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/RedshiftClusterMasterUserPasswordRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/ResourceWithExplicitNameRule.rb +1 -1
- data/lib/cfn-nag/custom_rules/SecretsManagerSecretKmsKeyIdRule.rb +1 -1
- data/lib/cfn-nag/custom_rules/SecurityGroupIngressOpenToWorldRule.rb +1 -1
- data/lib/cfn-nag/custom_rules/SecurityGroupIngressPortRangeRule.rb +1 -1
- data/lib/cfn-nag/custom_rules/SecurityGroupMissingEgressRule.rb +1 -1
- data/lib/cfn-nag/custom_rules/SecurityGroupRuleDescriptionRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/base.rb +7 -1
- data/lib/cfn-nag/deny_list_loader.rb +43 -0
- data/lib/cfn-nag/iam_complexity_metric/spcm.rb +3 -3
- data/lib/cfn-nag/result_view/json_results.rb +1 -1
- data/lib/cfn-nag/result_view/sarif_results.rb +103 -0
- data/lib/cfn-nag/result_view/stdout_results.rb +1 -1
- data/lib/cfn-nag/rule_definition.rb +6 -3
- data/lib/cfn-nag/rule_registry.rb +1 -0
- data/lib/cfn-nag/util/enforce_reference_parameter.rb +1 -1
- data/lib/cfn-nag/version.rb +6 -0
- data/lib/cfn-nag/violation.rb +11 -0
- data/lib/cfn-nag/violation_filtering.rb +9 -9
- metadata +7 -5
- data/lib/cfn-nag/blacklist_loader.rb +0 -43
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: d0dd505f40c9fd504634b10223a8742375032a6fd225febe29460692dae4b5d2
|
|
4
|
+
data.tar.gz: 6e535f22dde6837b2384a94a95f1a115ca0ec89c30450793ae490b092d034622
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0d75d174639ebf1056c2add11c6acca90f273d545dd825703a710b1e15c0483c90dee85a161d4c7d4b6261371ac7d3ec1b6df3f80facbec2f59cb0adf683b060
|
|
7
|
+
data.tar.gz: cd3d89960bf8662a99e2a6e180c46ad587413872e30085e77b7db625a46a1e9d0d8d7a742debe3cdd7b8f8f51bc07190696eb9271479cf0ce13ee8b707320e05
|
data/bin/cfn_nag_rules
CHANGED
|
@@ -6,7 +6,7 @@ require 'cfn-nag'
|
|
|
6
6
|
require 'rubygems/specification'
|
|
7
7
|
|
|
8
8
|
opts = Optimist.options do
|
|
9
|
-
version
|
|
9
|
+
version CfnNagVersion::VERSION
|
|
10
10
|
|
|
11
11
|
opt :rule_directory, 'Extra rule directories', type: :io,
|
|
12
12
|
required: false,
|
|
@@ -27,12 +27,12 @@ end
|
|
|
27
27
|
|
|
28
28
|
profile_definition = nil
|
|
29
29
|
unless opts[:profile_path].nil?
|
|
30
|
-
profile_definition =
|
|
30
|
+
profile_definition = File.read(opts[:profile_path])
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
rule_repository_definitions = []
|
|
34
34
|
opts[:rule_repository]&.each do |rule_repository|
|
|
35
|
-
rule_repository_definitions <<
|
|
35
|
+
rule_repository_definitions << File.read(rule_repository)
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
rule_dumper = CfnNagRuleDumper.new(profile_definition: profile_definition,
|
data/bin/spcm_scan
CHANGED
data/lib/cfn-nag/base_rule.rb
CHANGED
|
@@ -20,10 +20,16 @@ class CfnNag
|
|
|
20
20
|
logical_resource_ids = audit_impl(cfn_model)
|
|
21
21
|
return if logical_resource_ids.empty?
|
|
22
22
|
|
|
23
|
+
violation(logical_resource_ids)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def violation(logical_resource_ids, line_numbers = nil)
|
|
23
27
|
Violation.new(id: rule_id,
|
|
28
|
+
name: self.class.name,
|
|
24
29
|
type: rule_type,
|
|
25
30
|
message: rule_text,
|
|
26
|
-
logical_resource_ids: logical_resource_ids
|
|
31
|
+
logical_resource_ids: logical_resource_ids,
|
|
32
|
+
line_numbers: line_numbers)
|
|
27
33
|
end
|
|
28
34
|
end
|
|
29
35
|
end
|
data/lib/cfn-nag/cfn_nag.rb
CHANGED
|
@@ -8,6 +8,7 @@ require_relative 'result_view/stdout_results'
|
|
|
8
8
|
require_relative 'result_view/simple_stdout_results'
|
|
9
9
|
require_relative 'result_view/colored_stdout_results'
|
|
10
10
|
require_relative 'result_view/json_results'
|
|
11
|
+
require_relative 'result_view/sarif_results'
|
|
11
12
|
require 'cfn-model'
|
|
12
13
|
|
|
13
14
|
# Top-level CfnNag class for running profiles
|
|
@@ -55,8 +56,8 @@ class CfnNag
|
|
|
55
56
|
parameter_values_path: nil,
|
|
56
57
|
condition_values_path: nil,
|
|
57
58
|
template_pattern: DEFAULT_TEMPLATE_PATTERN)
|
|
58
|
-
parameter_values_string = parameter_values_path.nil? ? nil :
|
|
59
|
-
condition_values_string = condition_values_path.nil? ? nil :
|
|
59
|
+
parameter_values_string = parameter_values_path.nil? ? nil : File.read(parameter_values_path)
|
|
60
|
+
condition_values_string = condition_values_path.nil? ? nil : File.read(condition_values_path)
|
|
60
61
|
|
|
61
62
|
templates = TemplateDiscovery.new.discover_templates(input_json_path: input_path,
|
|
62
63
|
template_pattern: template_pattern)
|
|
@@ -64,7 +65,7 @@ class CfnNag
|
|
|
64
65
|
templates.each do |template|
|
|
65
66
|
aggregate_results << {
|
|
66
67
|
filename: template,
|
|
67
|
-
file_results: audit(cloudformation_string:
|
|
68
|
+
file_results: audit(cloudformation_string: File.read(template),
|
|
68
69
|
parameter_values_string: parameter_values_string,
|
|
69
70
|
condition_values_string: condition_values_string)
|
|
70
71
|
}
|
|
@@ -93,13 +94,13 @@ class CfnNag
|
|
|
93
94
|
@config.custom_rule_loader.rule_definitions
|
|
94
95
|
)
|
|
95
96
|
|
|
96
|
-
violations =
|
|
97
|
+
violations = filter_violations_by_deny_list_and_profile(violations)
|
|
97
98
|
violations = mark_line_numbers(violations, cfn_model)
|
|
98
99
|
rescue RuleRepoException, Psych::SyntaxError, ParserError => fatal_error
|
|
99
|
-
violations << fatal_violation(fatal_error.to_s)
|
|
100
|
+
violations << Violation.fatal_violation(fatal_error.to_s)
|
|
100
101
|
rescue JSON::ParserError => json_parameters_error
|
|
101
102
|
error = "JSON Parameter values parse error: #{json_parameters_error}"
|
|
102
|
-
violations << fatal_violation(error)
|
|
103
|
+
violations << Violation.fatal_violation(error)
|
|
103
104
|
end
|
|
104
105
|
|
|
105
106
|
violations = prune_fatal_violations(violations) if @config.ignore_fatal
|
|
@@ -112,7 +113,7 @@ class CfnNag
|
|
|
112
113
|
|
|
113
114
|
def render_results(aggregate_results:,
|
|
114
115
|
output_format:)
|
|
115
|
-
results_renderer(output_format).new.render(aggregate_results)
|
|
116
|
+
results_renderer(output_format).new.render(aggregate_results, @config.custom_rule_loader.rule_definitions)
|
|
116
117
|
end
|
|
117
118
|
|
|
118
119
|
private
|
|
@@ -127,21 +128,21 @@ class CfnNag
|
|
|
127
128
|
violations
|
|
128
129
|
end
|
|
129
130
|
|
|
130
|
-
def
|
|
131
|
+
def filter_violations_by_deny_list_and_profile(violations)
|
|
131
132
|
violations = filter_violations_by_profile(
|
|
132
133
|
profile_definition: @config.profile_definition,
|
|
133
134
|
rule_definitions: @config.custom_rule_loader.rule_definitions,
|
|
134
135
|
violations: violations
|
|
135
136
|
)
|
|
136
137
|
|
|
137
|
-
# this must come after -
|
|
138
|
-
|
|
139
|
-
|
|
138
|
+
# this must come after - deny list should always win
|
|
139
|
+
filter_violations_by_deny_list(
|
|
140
|
+
deny_list_definition: @config.deny_list_definition,
|
|
140
141
|
rule_definitions: @config.custom_rule_loader.rule_definitions,
|
|
141
142
|
violations: violations
|
|
142
143
|
)
|
|
143
|
-
rescue StandardError =>
|
|
144
|
-
violations << fatal_violation(
|
|
144
|
+
rescue StandardError => deny_list_or_profile_parse_error
|
|
145
|
+
violations << Violation.fatal_violation(deny_list_or_profile_parse_error.to_s)
|
|
145
146
|
violations
|
|
146
147
|
end
|
|
147
148
|
|
|
@@ -152,17 +153,12 @@ class CfnNag
|
|
|
152
153
|
}
|
|
153
154
|
end
|
|
154
155
|
|
|
155
|
-
def fatal_violation(message)
|
|
156
|
-
Violation.new(id: 'FATAL',
|
|
157
|
-
type: Violation::FAILING_VIOLATION,
|
|
158
|
-
message: message)
|
|
159
|
-
end
|
|
160
|
-
|
|
161
156
|
def results_renderer(output_format)
|
|
162
157
|
registry = {
|
|
163
158
|
'colortxt' => ColoredStdoutResults,
|
|
164
159
|
'txt' => SimpleStdoutResults,
|
|
165
|
-
'json' => JsonResults
|
|
160
|
+
'json' => JsonResults,
|
|
161
|
+
'sarif' => SarifResults
|
|
166
162
|
}
|
|
167
163
|
registry[output_format]
|
|
168
164
|
end
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
class CfnNagConfig
|
|
4
4
|
# rubocop:disable Metrics/ParameterLists
|
|
5
5
|
def initialize(profile_definition: nil,
|
|
6
|
-
|
|
6
|
+
deny_list_definition: nil,
|
|
7
7
|
rule_directory: nil,
|
|
8
8
|
allow_suppression: true,
|
|
9
9
|
print_suppression: false,
|
|
@@ -21,7 +21,7 @@ class CfnNagConfig
|
|
|
21
21
|
rule_repository_definitions: rule_repository_definitions
|
|
22
22
|
)
|
|
23
23
|
@profile_definition = profile_definition
|
|
24
|
-
@
|
|
24
|
+
@deny_list_definition = deny_list_definition
|
|
25
25
|
@fail_on_warnings = fail_on_warnings
|
|
26
26
|
@rule_repositories = rule_repositories
|
|
27
27
|
@rule_arguments = rule_arguments
|
|
@@ -29,6 +29,6 @@ class CfnNagConfig
|
|
|
29
29
|
end
|
|
30
30
|
# rubocop:enable Metrics/ParameterLists
|
|
31
31
|
|
|
32
|
-
attr_reader :rule_arguments, :rule_directory, :custom_rule_loader, :profile_definition, :
|
|
32
|
+
attr_reader :rule_arguments, :rule_directory, :custom_rule_loader, :profile_definition, :deny_list_definition, \
|
|
33
33
|
:fail_on_warnings, :rule_repositories, :ignore_fatal
|
|
34
34
|
end
|
|
@@ -7,7 +7,7 @@ require 'cfn-nag/cfn_nag_config'
|
|
|
7
7
|
class CfnNagExecutor
|
|
8
8
|
def initialize
|
|
9
9
|
@profile_definition = nil
|
|
10
|
-
@
|
|
10
|
+
@deny_list_definition = nil
|
|
11
11
|
@parameter_values_string = nil
|
|
12
12
|
@condition_values_string = nil
|
|
13
13
|
@rule_repository_definitions = []
|
|
@@ -74,9 +74,9 @@ class CfnNagExecutor
|
|
|
74
74
|
end
|
|
75
75
|
|
|
76
76
|
def validate_options(opts)
|
|
77
|
-
unless opts[:output_format].nil? || %w[colortxt txt json].include?(opts[:output_format])
|
|
77
|
+
unless opts[:output_format].nil? || %w[colortxt txt json sarif].include?(opts[:output_format])
|
|
78
78
|
Optimist.die(:output_format,
|
|
79
|
-
'Must be colortxt, txt, or
|
|
79
|
+
'Must be colortxt, txt, json or sarif')
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
opts[:rule_arguments]&.each do |rule_argument|
|
|
@@ -89,7 +89,7 @@ class CfnNagExecutor
|
|
|
89
89
|
def execute_io_options(opts)
|
|
90
90
|
@profile_definition = read_conditionally(opts[:profile_path])
|
|
91
91
|
|
|
92
|
-
@
|
|
92
|
+
@deny_list_definition = read_conditionally(opts[:deny_list_path]) || read_conditionally(opts[:blacklist_path])
|
|
93
93
|
|
|
94
94
|
@parameter_values_string = read_conditionally(opts[:parameter_values_path])
|
|
95
95
|
|
|
@@ -98,13 +98,13 @@ class CfnNagExecutor
|
|
|
98
98
|
@rule_arguments_string = read_conditionally(opts[:rule_arguments_path])
|
|
99
99
|
|
|
100
100
|
opts[:rule_repository]&.each do |rule_repository|
|
|
101
|
-
@rule_repository_definitions <<
|
|
101
|
+
@rule_repository_definitions << File.read(rule_repository)
|
|
102
102
|
end
|
|
103
103
|
end
|
|
104
104
|
|
|
105
105
|
def read_conditionally(path)
|
|
106
106
|
unless path.nil?
|
|
107
|
-
|
|
107
|
+
File.read(path)
|
|
108
108
|
end
|
|
109
109
|
end
|
|
110
110
|
|
|
@@ -122,7 +122,7 @@ class CfnNagExecutor
|
|
|
122
122
|
def cfn_nag_config(opts)
|
|
123
123
|
CfnNagConfig.new(
|
|
124
124
|
profile_definition: @profile_definition,
|
|
125
|
-
|
|
125
|
+
deny_list_definition: @deny_list_definition,
|
|
126
126
|
rule_directory: opts[:rule_directory],
|
|
127
127
|
allow_suppression: opts[:allow_suppression],
|
|
128
128
|
print_suppression: opts[:print_suppression],
|
data/lib/cfn-nag/cli_options.rb
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'optimist'
|
|
4
|
+
require_relative 'version'
|
|
4
5
|
|
|
5
6
|
# rubocop:disable Metrics/ClassLength
|
|
6
7
|
class Options
|
|
7
8
|
@custom_rule_exceptions_message = 'Isolate custom rule exceptions - just ' \
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
'emit the exception without stack trace ' \
|
|
10
|
+
'and keep chugging'
|
|
10
11
|
|
|
11
|
-
@version =
|
|
12
|
+
@version = CfnNagVersion::VERSION
|
|
12
13
|
|
|
13
14
|
def self.for(type)
|
|
14
15
|
case type
|
|
@@ -25,7 +26,7 @@ class Options
|
|
|
25
26
|
# rubocop:disable Metrics/MethodLength
|
|
26
27
|
def self.file_options
|
|
27
28
|
options_message = '[options] <cloudformation template path ...>|' \
|
|
28
|
-
|
|
29
|
+
'<cloudformation template in STDIN>'
|
|
29
30
|
custom_rule_exceptions_message = @custom_rule_exceptions_message
|
|
30
31
|
version = @version
|
|
31
32
|
|
|
@@ -58,8 +59,13 @@ class Options
|
|
|
58
59
|
type: :string,
|
|
59
60
|
required: false,
|
|
60
61
|
default: nil
|
|
62
|
+
opt :deny_list_path,
|
|
63
|
+
'Path to a deny list file',
|
|
64
|
+
type: :string,
|
|
65
|
+
required: false,
|
|
66
|
+
default: nil
|
|
61
67
|
opt :blacklist_path,
|
|
62
|
-
'Path to a
|
|
68
|
+
'(Deprecated) Path to a deny list file',
|
|
63
69
|
type: :string,
|
|
64
70
|
required: false,
|
|
65
71
|
default: nil
|
|
@@ -84,7 +90,7 @@ class Options
|
|
|
84
90
|
required: false,
|
|
85
91
|
default: false
|
|
86
92
|
opt :output_format,
|
|
87
|
-
'Format of results: [txt, json, colortxt]',
|
|
93
|
+
'Format of results: [txt, json, colortxt, sarif]',
|
|
88
94
|
type: :string,
|
|
89
95
|
default: 'colortxt'
|
|
90
96
|
opt :rule_repository,
|
|
@@ -127,7 +133,7 @@ class Options
|
|
|
127
133
|
type: :string,
|
|
128
134
|
required: true
|
|
129
135
|
opt :output_format,
|
|
130
|
-
'Format of results: [txt, json, colortxt]',
|
|
136
|
+
'Format of results: [txt, json, colortxt, sarif]',
|
|
131
137
|
type: :string,
|
|
132
138
|
default: 'colortxt'
|
|
133
139
|
opt :debug,
|
|
@@ -145,8 +151,13 @@ class Options
|
|
|
145
151
|
type: :string,
|
|
146
152
|
required: false,
|
|
147
153
|
default: nil
|
|
154
|
+
opt :deny_list_path,
|
|
155
|
+
'Path to a deny list file',
|
|
156
|
+
type: :string,
|
|
157
|
+
required: false,
|
|
158
|
+
default: nil
|
|
148
159
|
opt :blacklist_path,
|
|
149
|
-
'Path to a
|
|
160
|
+
'(Deprecated) Path to a deny list file',
|
|
150
161
|
type: :string,
|
|
151
162
|
required: false,
|
|
152
163
|
default: nil
|
|
@@ -8,7 +8,7 @@ require_relative 'base'
|
|
|
8
8
|
class AlexaASKSkillAuthenticationConfigurationClientSecretRule < BaseRule
|
|
9
9
|
def rule_text
|
|
10
10
|
'Alexa ASK Skill AuthenticationConfiguration ClientSecret must not be ' \
|
|
11
|
-
|
|
11
|
+
'a plaintext string or a Ref to a NoEcho Parameter with a Default value.'
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def rule_type
|
|
@@ -8,7 +8,7 @@ require_relative 'base'
|
|
|
8
8
|
class AlexaASKSkillAuthenticationConfigurationRefreshTokenRule < BaseRule
|
|
9
9
|
def rule_text
|
|
10
10
|
'Alexa ASK Skill AuthenticationConfiguration RefreshToken must not be ' \
|
|
11
|
-
|
|
11
|
+
'a plaintext string or a Ref to a NoEcho Parameter with a Default value.'
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def rule_type
|
|
@@ -6,7 +6,7 @@ require_relative 'sub_property_with_list_password_base_rule'
|
|
|
6
6
|
class AmazonMQBrokerUsersPasswordRule < SubPropertyWithListPasswordBaseRule
|
|
7
7
|
def rule_text
|
|
8
8
|
'AmazonMQ Broker Users Password must not be a plaintext string or a Ref to a Parameter with a Default value. ' \
|
|
9
|
-
|
|
9
|
+
'Can be Ref to a NoEcho Parameter without a Default, or a dynamic reference to a secretsmanager value.'
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def rule_type
|
|
@@ -6,8 +6,8 @@ require_relative 'password_base_rule'
|
|
|
6
6
|
class AmplifyAppAccessTokenRule < PasswordBaseRule
|
|
7
7
|
def rule_text
|
|
8
8
|
'Amplify App AccessToken must not be a plaintext string ' \
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
'or a Ref to a Parameter with a Default value. ' \
|
|
10
|
+
'Can be Ref to a NoEcho Parameter without a Default, or a dynamic reference to a secretsmanager value.'
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def rule_type
|
|
@@ -6,8 +6,8 @@ require_relative 'password_base_rule'
|
|
|
6
6
|
class AmplifyAppBasicAuthConfigPasswordRule < PasswordBaseRule
|
|
7
7
|
def rule_text
|
|
8
8
|
'Amplify App BasicAuthConfig Password must not be a plaintext string ' \
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
'or a Ref to a Parameter with a Default value. ' \
|
|
10
|
+
'Can be Ref to a NoEcho Parameter without a Default, or a dynamic reference to a secretsmanager value.'
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def rule_type
|
|
@@ -6,8 +6,8 @@ require_relative 'password_base_rule'
|
|
|
6
6
|
class AmplifyAppOauthTokenRule < PasswordBaseRule
|
|
7
7
|
def rule_text
|
|
8
8
|
'Amplify App OauthToken must not be a plaintext string ' \
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
'or a Ref to a Parameter with a Default value. ' \
|
|
10
|
+
'Can be Ref to a NoEcho Parameter without a Default, or a dynamic reference to a secretsmanager value.'
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def rule_type
|
|
@@ -6,8 +6,8 @@ require_relative 'password_base_rule'
|
|
|
6
6
|
class AmplifyBranchBasicAuthConfigPasswordRule < PasswordBaseRule
|
|
7
7
|
def rule_text
|
|
8
8
|
'Amplify Branch BasicAuthConfig Password must not be a plaintext ' \
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
'string or a Ref to a Parameter with a Default value. ' \
|
|
10
|
+
'Can be Ref to a NoEcho Parameter without a Default, or a dynamic reference to a secretsmanager value.'
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def rule_type
|
|
@@ -6,7 +6,7 @@ require_relative 'base'
|
|
|
6
6
|
class ApiGatewayAccessLoggingRule < BaseRule
|
|
7
7
|
def rule_text
|
|
8
8
|
'ApiGateway Deployment resource should have AccessLogSetting property configured when creating an ' \
|
|
9
|
-
|
|
9
|
+
'API Stage itself (through specifying the StageName and StageDescription properties).'
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def rule_type
|
|
@@ -6,7 +6,7 @@ require_relative 'base'
|
|
|
6
6
|
class ApiGatewayCacheEncryptedRule < BaseRule
|
|
7
7
|
def rule_text
|
|
8
8
|
'ApiGateway Deployment should have cache data encryption enabled when caching is enabled' \
|
|
9
|
-
|
|
9
|
+
' in StageDescription properties'
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def rule_type
|
|
@@ -6,7 +6,7 @@ require_relative 'base'
|
|
|
6
6
|
class ApiGatewayMethodAuthorizationTypeRule < BaseRule
|
|
7
7
|
def rule_text
|
|
8
8
|
"AWS::ApiGateway::Method should not have AuthorizationType set to 'NONE' unless it is of " \
|
|
9
|
-
|
|
9
|
+
'HttpMethod: OPTIONS.'
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def rule_type
|
|
@@ -6,9 +6,9 @@ require_relative 'password_base_rule'
|
|
|
6
6
|
class AppStreamDirectoryConfigServiceAccountCredentialsAccountPasswordRule < PasswordBaseRule
|
|
7
7
|
def rule_text
|
|
8
8
|
'AppStream DirectoryConfig ServiceAccountCredentials AccountPassword ' \
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
'must not be a plaintext string or a Ref to a Parameter ' \
|
|
10
|
+
'with a Default value. ' \
|
|
11
|
+
'Can be Ref to a NoEcho Parameter without a Default, or a dynamic reference to a secretsmanager value.'
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def rule_type
|
data/lib/cfn-nag/custom_rules/CodePipelineWebhookAuthenticationConfigurationSecretTokenRule.rb
CHANGED
|
@@ -6,8 +6,8 @@ require_relative 'password_base_rule'
|
|
|
6
6
|
class CodePipelineWebhookAuthenticationConfigurationSecretTokenRule < PasswordBaseRule
|
|
7
7
|
def rule_text
|
|
8
8
|
'CodePipeline Webhook AuthenticationConfiguration SecretToken must not be ' \
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
'a plaintext string or a Ref to a Parameter with a Default value. ' \
|
|
10
|
+
'Can be Ref to a NoEcho Parameter without a Default, or a dynamic reference to a secretsmanager value.'
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def rule_type
|
|
@@ -7,7 +7,7 @@ require_relative 'base'
|
|
|
7
7
|
class CognitoIdentityPoolAllowUnauthenticatedIdentitiesRule < BaseRule
|
|
8
8
|
def rule_text
|
|
9
9
|
'AWS::Cognito::IdentityPool AllowUnauthenticatedIdentities property should be false ' \
|
|
10
|
-
|
|
10
|
+
'but CAN be true if proper restrictive IAM roles and permissions are established for unauthenticated users.'
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def rule_type
|
|
@@ -6,8 +6,8 @@ require_relative 'password_base_rule'
|
|
|
6
6
|
class DMSEndpointMongoDbSettingsPasswordRule < PasswordBaseRule
|
|
7
7
|
def rule_text
|
|
8
8
|
'DMS Endpoint MongoDbSettings Password must not be a plaintext string ' \
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
'or a Ref to a Parameter with a Default value. ' \
|
|
10
|
+
'Can be Ref to a NoEcho Parameter without a Default, or a dynamic reference to a secretsmanager value.'
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def rule_type
|
|
@@ -6,8 +6,8 @@ require_relative 'password_base_rule'
|
|
|
6
6
|
class DMSEndpointPasswordRule < PasswordBaseRule
|
|
7
7
|
def rule_text
|
|
8
8
|
'DMS Endpoint password must not be a plaintext string ' \
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
'or a Ref to a Parameter with a Default value. ' \
|
|
10
|
+
'Can be Ref to a NoEcho Parameter without a Default, or a dynamic reference to a secretsmanager value.'
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def rule_type
|
|
@@ -7,8 +7,8 @@ require_relative 'password_base_rule'
|
|
|
7
7
|
class DirectoryServiceMicrosoftADPasswordRule < PasswordBaseRule
|
|
8
8
|
def rule_text
|
|
9
9
|
'Directory Service Microsoft AD password must not be a plaintext string ' \
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
'or a Ref to a Parameter with a Default value. ' \
|
|
11
|
+
'Can be Ref to a NoEcho Parameter without a Default, or a dynamic reference to a secretsmanager/ssm-secure value.'
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def rule_type
|
|
@@ -7,8 +7,8 @@ require_relative 'password_base_rule'
|
|
|
7
7
|
class DirectoryServiceSimpleADPasswordRule < PasswordBaseRule
|
|
8
8
|
def rule_text
|
|
9
9
|
'DirectoryService SimpleAD password must not be a plaintext string ' \
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
'or a Ref to a Parameter with a Default value. ' \
|
|
11
|
+
'Can be Ref to a NoEcho Parameter without a Default, or a dynamic reference to a secretsmanager/ssm-secure value.'
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def rule_type
|
|
@@ -6,8 +6,8 @@ require_relative 'password_base_rule'
|
|
|
6
6
|
class DocDBDBClusterMasterUserPasswordRule < PasswordBaseRule
|
|
7
7
|
def rule_text
|
|
8
8
|
'DocDB DB Cluster master user password must not be a plaintext string ' \
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
'or a Ref to a Parameter with a Default value. ' \
|
|
10
|
+
'Can be Ref to a NoEcho Parameter without a Default, or a dynamic reference to a secretsmanager value.'
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def rule_type
|
|
@@ -6,7 +6,7 @@ require_relative 'base'
|
|
|
6
6
|
class EC2NetworkAclEntryProtocolRule < BaseRule
|
|
7
7
|
def rule_text
|
|
8
8
|
'To avoid opening all ports for Allow rules, EC2 NetworkACL Entry Protocol should be either 6 (for TCP), 17 ' \
|
|
9
|
-
|
|
9
|
+
'(for UDP), 1 (for ICMP), or 58 (for ICMPv6, which must include an IPv6 CIDR block, ICMP type, and code).'
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
def rule_type
|
|
@@ -53,12 +53,8 @@ class EC2NetworkAclEntryProtocolRule < BaseRule
|
|
|
53
53
|
|
|
54
54
|
def violating_network_acl_entries?(network_acl_entry)
|
|
55
55
|
if rule_action_allow?(network_acl_entry)
|
|
56
|
-
|
|
57
|
-
icmpv6_protocol?(network_acl_entry)
|
|
58
|
-
false
|
|
59
|
-
else
|
|
60
|
-
true
|
|
61
|
-
end
|
|
56
|
+
!(tcp_udp_icmp_protocol?(network_acl_entry) ||
|
|
57
|
+
icmpv6_protocol?(network_acl_entry))
|
|
62
58
|
end
|
|
63
59
|
end
|
|
64
60
|
end
|
|
@@ -18,9 +18,7 @@ class EKSClusterEncryptionRule < BaseRule
|
|
|
18
18
|
|
|
19
19
|
def audit_impl(cfn_model)
|
|
20
20
|
violating_clusters = cfn_model.resources_by_type('AWS::EKS::Cluster').select do |cluster|
|
|
21
|
-
if cluster.encryptionConfig.nil?
|
|
22
|
-
true
|
|
23
|
-
elsif violating_configs?(cluster)
|
|
21
|
+
if cluster.encryptionConfig.nil? || violating_configs?(cluster)
|
|
24
22
|
true
|
|
25
23
|
else
|
|
26
24
|
violating_providers?(cluster)
|
|
@@ -6,8 +6,8 @@ require_relative 'password_base_rule'
|
|
|
6
6
|
class EMRClusterKerberosAttributesADDomainJoinPasswordRule < PasswordBaseRule
|
|
7
7
|
def rule_text
|
|
8
8
|
'EMR Cluster KerberosAttributes AD Domain JoinPassword must not be a ' \
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
'plaintext string or a Ref to a Parameter with a Default value. ' \
|
|
10
|
+
'Can be Ref to a NoEcho Parameter without a Default, or a dynamic reference to a secretsmanager value.'
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def rule_type
|
data/lib/cfn-nag/custom_rules/EMRClusterKerberosAttributesCrossRealmTrustPrincipalPasswordRule.rb
CHANGED
|
@@ -6,9 +6,9 @@ require_relative 'password_base_rule'
|
|
|
6
6
|
class EMRClusterKerberosAttributesCrossRealmTrustPrincipalPasswordRule < PasswordBaseRule
|
|
7
7
|
def rule_text
|
|
8
8
|
'EMR Cluster KerberosAttributes CrossRealmTrustPrincipal Password must ' \
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
'not be a plaintext string or a Ref to a Parameter with a ' \
|
|
10
|
+
'Default value. ' \
|
|
11
|
+
'Can be Ref to a NoEcho Parameter without a Default, or a dynamic reference to a secretsmanager value.'
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
def rule_type
|
|
@@ -6,8 +6,8 @@ require_relative 'password_base_rule'
|
|
|
6
6
|
class EMRClusterKerberosAttributesKdcAdminPasswordRule < PasswordBaseRule
|
|
7
7
|
def rule_text
|
|
8
8
|
'EMR Cluster KerberosAttributes KdcAdmin Password must not be a ' \
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
'plaintext string or a Ref to a Parameter with a Default value. ' \
|
|
10
|
+
'Can be Ref to a NoEcho Parameter without a Default, or a dynamic reference to a secretsmanager value.'
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def rule_type
|
|
@@ -6,8 +6,8 @@ require_relative 'password_base_rule'
|
|
|
6
6
|
class ElastiCacheReplicationGroupAuthTokenRule < PasswordBaseRule
|
|
7
7
|
def rule_text
|
|
8
8
|
'ElastiCache ReplicationGroup AuthToken must not be a plaintext string ' \
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
'or a Ref to a Parameter with a Default value. ' \
|
|
10
|
+
'Can be Ref to a NoEcho Parameter without a Default, or a dynamic reference to a secretsmanager/ssm-secure value.'
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def rule_type
|
|
@@ -18,6 +18,8 @@ class GameLiftFleetInboundPortRangeRule < BaseRule
|
|
|
18
18
|
|
|
19
19
|
def audit_impl(cfn_model)
|
|
20
20
|
violating_gamelift_fleets = cfn_model.resources_by_type('AWS::GameLift::Fleet').select do |gamelift_fleet|
|
|
21
|
+
next false if gamelift_fleet.eC2InboundPermissions.nil?
|
|
22
|
+
|
|
21
23
|
violating_permissions = gamelift_fleet.eC2InboundPermissions.select do |permission|
|
|
22
24
|
# Cast to strings incase template provided mixed types
|
|
23
25
|
permission['FromPort'].to_s != permission['ToPort'].to_s
|
|
@@ -6,8 +6,8 @@ require_relative 'password_base_rule'
|
|
|
6
6
|
class IAMUserLoginProfilePasswordRule < PasswordBaseRule
|
|
7
7
|
def rule_text
|
|
8
8
|
'IAM User LoginProfile Password must not be a plaintext string or ' \
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
'a Ref to a Parameter with a Default value. ' \
|
|
10
|
+
'Can be Ref to a NoEcho Parameter without a Default, or a dynamic reference to a secretsmanager value.'
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
def rule_type
|