cfn-nag 0.5.61 → 0.6.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/spcm_scan +69 -0
- data/lib/cfn-nag/cfn_nag.rb +1 -0
- data/lib/cfn-nag/cfn_nag_config.rb +4 -1
- data/lib/cfn-nag/cfn_nag_executor.rb +22 -1
- data/lib/cfn-nag/cli_options.rb +18 -0
- data/lib/cfn-nag/custom_rule_loader.rb +23 -72
- data/lib/cfn-nag/custom_rules/AmazonMQBrokerUsersPasswordRule.rb +2 -2
- data/lib/cfn-nag/custom_rules/AmplifyAppAccessTokenRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/AmplifyAppBasicAuthConfigPasswordRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/AmplifyAppOauthTokenRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/AmplifyBranchBasicAuthConfigPasswordRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/ApiGatewayV2AccessLoggingRule.rb +1 -1
- data/lib/cfn-nag/custom_rules/AppStreamDirectoryConfigServiceAccountCredentialsAccountPasswordRule.rb +3 -2
- data/lib/cfn-nag/custom_rules/CodePipelineWebhookAuthenticationConfigurationSecretTokenRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/DMSEndpointMongoDbSettingsPasswordRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/DMSEndpointPasswordRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/DirectoryServiceMicrosoftADPasswordRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/DirectoryServiceSimpleADPasswordRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/DocDBDBClusterMasterUserPasswordRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/EMRClusterKerberosAttributesADDomainJoinPasswordRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/EMRClusterKerberosAttributesCrossRealmTrustPrincipalPasswordRule.rb +3 -2
- data/lib/cfn-nag/custom_rules/EMRClusterKerberosAttributesKdcAdminPasswordRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/ElastiCacheReplicationGroupAuthTokenRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/IAMUserLoginProfilePasswordRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/KinesisFirehoseDeliveryStreamRedshiftDestinationConfigurationPasswordRule.rb +3 -2
- data/lib/cfn-nag/custom_rules/KinesisFirehoseDeliveryStreamSplunkDestinationConfigurationHECTokenRule.rb +3 -2
- data/lib/cfn-nag/custom_rules/LambdaPermissionEventSourceTokenRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/OpsWorksAppAppSourcePasswordRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/OpsWorksAppSslConfigurationPrivateKeyRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/OpsWorksStackCustomCookbooksSourcePasswordRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/OpsWorksStackRdsDbInstancesDbPasswordRule.rb +3 -2
- data/lib/cfn-nag/custom_rules/PinpointAPNSChannelPrivateKeyRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/PinpointAPNSChannelTokenKeyRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/PinpointAPNSSandboxChannelPrivateKeyRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/PinpointAPNSSandboxChannelTokenKeyRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/PinpointAPNSVoipChannelPrivateKeyRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/PinpointAPNSVoipChannelTokenKeyRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/PinpointAPNSVoipSandboxChannelPrivateKeyRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/PinpointAPNSVoipSandboxChannelTokenKeyRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/RDSDBClusterMasterUserPasswordRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/RDSDBInstanceMasterUserPasswordRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/RDSDBInstanceMasterUsernameRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/RedshiftClusterMasterUserPasswordRule.rb +2 -1
- data/lib/cfn-nag/custom_rules/SPCMRule.rb +66 -0
- data/lib/cfn-nag/custom_rules/SecretsManagerSecretKmsKeyIdRule.rb +4 -3
- data/lib/cfn-nag/iam_complexity_metric/condition_metric.rb +85 -0
- data/lib/cfn-nag/iam_complexity_metric/html_results_renderer.rb +45 -0
- data/lib/cfn-nag/iam_complexity_metric/policy_document_metric.rb +11 -0
- data/lib/cfn-nag/iam_complexity_metric/spcm.rb +79 -0
- data/lib/cfn-nag/iam_complexity_metric/statement_metric.rb +104 -0
- data/lib/cfn-nag/iam_complexity_metric/weights.rb +22 -0
- data/lib/cfn-nag/metadata.rb +78 -0
- metadata +15 -5
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class HtmlRenderer
|
4
|
+
def render(results:)
|
5
|
+
output = '<html><body><table>'
|
6
|
+
results.each do |result|
|
7
|
+
output += '<tr><td><table><tr><td>'
|
8
|
+
output += result[:filename]
|
9
|
+
output += '</td></tr><tr><td>'
|
10
|
+
output += render_policy(result)
|
11
|
+
output += render_role(result)
|
12
|
+
output += '</td></tr></table></td></tr>'
|
13
|
+
end
|
14
|
+
output += '</table></body></html>'
|
15
|
+
output
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def render_policy(result)
|
21
|
+
output = ''
|
22
|
+
if result[:file_results]['AWS::IAM::Policy'] != {}
|
23
|
+
output += '<ul>'
|
24
|
+
result[:file_results]['AWS::IAM::Policy'].each do |k, v|
|
25
|
+
output += "<li>#{k}=#{v}</li>"
|
26
|
+
end
|
27
|
+
output += '</ul>'
|
28
|
+
end
|
29
|
+
output
|
30
|
+
end
|
31
|
+
|
32
|
+
def render_role(result)
|
33
|
+
output = ''
|
34
|
+
if result[:file_results]['AWS::IAM::Role'] != {}
|
35
|
+
output += '<ul>'
|
36
|
+
result[:file_results]['AWS::IAM::Role'].each do |role_id, policy_map|
|
37
|
+
policy_map.each do |policy_name, metric|
|
38
|
+
output += "<li>#{role_id}/#{policy_name}=#{metric}</li>"
|
39
|
+
end
|
40
|
+
end
|
41
|
+
output += '</ul>'
|
42
|
+
end
|
43
|
+
output
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'statement_metric'
|
4
|
+
|
5
|
+
class PolicyDocumentMetric
|
6
|
+
def metric(policy_document)
|
7
|
+
policy_document.statements.reduce(0) do |aggregate, statement|
|
8
|
+
aggregate + StatementMetric.new.metric(statement)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cfn-nag/template_discovery'
|
4
|
+
require 'cfn-model'
|
5
|
+
require_relative 'policy_document_metric'
|
6
|
+
|
7
|
+
class SPCM
|
8
|
+
DEFAULT_TEMPLATE_PATTERN = '..*\.json$|..*\.yaml$|..*\.yml$|..*\.template$'
|
9
|
+
|
10
|
+
def aggregate_metrics(input_path:,
|
11
|
+
parameter_values_path: nil,
|
12
|
+
condition_values_path: nil,
|
13
|
+
template_pattern: DEFAULT_TEMPLATE_PATTERN)
|
14
|
+
parameter_values_string = parameter_values_path.nil? ? nil : IO.read(parameter_values_path)
|
15
|
+
condition_values_string = condition_values_path.nil? ? nil : IO.read(condition_values_path)
|
16
|
+
|
17
|
+
templates = TemplateDiscovery.new.discover_templates(input_json_path: input_path,
|
18
|
+
template_pattern: template_pattern)
|
19
|
+
aggregate_results = []
|
20
|
+
templates.each do |template|
|
21
|
+
aggregate_results << {
|
22
|
+
filename: template,
|
23
|
+
file_results: metric(
|
24
|
+
cloudformation_string: IO.read(template),
|
25
|
+
parameter_values_string: parameter_values_string,
|
26
|
+
condition_values_string: condition_values_string
|
27
|
+
)
|
28
|
+
}
|
29
|
+
end
|
30
|
+
aggregate_results
|
31
|
+
end
|
32
|
+
|
33
|
+
def metric(cloudformation_string:, parameter_values_string: nil, condition_values_string: nil)
|
34
|
+
cfn_model = CfnParser.new.parse cloudformation_string,
|
35
|
+
parameter_values_string,
|
36
|
+
false,
|
37
|
+
condition_values_string
|
38
|
+
|
39
|
+
metric_impl(cfn_model)
|
40
|
+
end
|
41
|
+
|
42
|
+
def metric_impl(cfn_model)
|
43
|
+
policy_documents = {
|
44
|
+
'AWS::IAM::Policy' => {},
|
45
|
+
'AWS::IAM::Role' => {}
|
46
|
+
}
|
47
|
+
|
48
|
+
cfn_model.resources_by_type('AWS::IAM::Policy').each do |policy|
|
49
|
+
update_policy_metric(policy_documents, policy)
|
50
|
+
end
|
51
|
+
|
52
|
+
cfn_model.resources_by_type('AWS::IAM::Role').each do |role|
|
53
|
+
role.policy_objects.each do |policy|
|
54
|
+
update_role_policy_metric(policy_documents, role, policy)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
policy_documents
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def update_policy_metric(policy_documents, policy)
|
64
|
+
metric = PolicyDocumentMetric.new.metric(policy.policy_document)
|
65
|
+
policy_documents['AWS::IAM::Policy'][policy.logical_resource_id] = metric
|
66
|
+
end
|
67
|
+
|
68
|
+
def update_role_policy_metric(policy_documents, role, policy)
|
69
|
+
metric = PolicyDocumentMetric.new.metric(policy.policy_document)
|
70
|
+
|
71
|
+
if policy_documents['AWS::IAM::Role'][role.logical_resource_id]
|
72
|
+
policy_documents['AWS::IAM::Role'][role.logical_resource_id][policy.policy_name.to_s] = metric
|
73
|
+
else
|
74
|
+
policy_documents['AWS::IAM::Role'][role.logical_resource_id] = {
|
75
|
+
policy.policy_name.to_s => metric
|
76
|
+
}
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'weights'
|
4
|
+
require_relative 'condition_metric'
|
5
|
+
require 'set'
|
6
|
+
|
7
|
+
class StatementMetric
|
8
|
+
include Weights
|
9
|
+
|
10
|
+
# rubocop:disable Metrics/AbcSize
|
11
|
+
def metric(statement)
|
12
|
+
aggregate = weights[:Base_Statement]
|
13
|
+
|
14
|
+
aggregate += effect_metrics(statement)
|
15
|
+
aggregate += inversion_metrics(statement)
|
16
|
+
aggregate += extra_service_count(statement) * weights[:Extra_Service]
|
17
|
+
aggregate += misaligned_resource_action_count(statement) * weights[:Resource_Action_NotAligned]
|
18
|
+
aggregate += mixed_wildcard(statement) * weights[:Mixed_Wildcard]
|
19
|
+
|
20
|
+
aggregate += ConditionMetric.new.metric(statement) unless statement.condition.nil?
|
21
|
+
|
22
|
+
aggregate
|
23
|
+
end
|
24
|
+
# rubocop:enable Metrics/AbcSize
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def effect_metrics(statement)
|
29
|
+
aggregate = 0
|
30
|
+
aggregate += weights[:Deny] if statement.effect == 'Deny'
|
31
|
+
aggregate += weights[:Allow] if statement.effect == 'Allow'
|
32
|
+
aggregate
|
33
|
+
end
|
34
|
+
|
35
|
+
def inversion_metrics(statement)
|
36
|
+
aggregate = 0
|
37
|
+
aggregate += weights[:NotAction] unless statement.not_actions.empty?
|
38
|
+
aggregate += weights[:NotResource] unless statement.not_resources.empty?
|
39
|
+
aggregate
|
40
|
+
end
|
41
|
+
|
42
|
+
def mixed_wildcard(statement)
|
43
|
+
count = 0
|
44
|
+
count += 1 if action_service_names(statement).include?('*') && action_service_names(statement).size > 1
|
45
|
+
count += 1 if resource_service_names(statement).include?('*') && resource_service_names(statement).size > 1
|
46
|
+
count
|
47
|
+
end
|
48
|
+
|
49
|
+
def misaligned_resource_action_count(statement)
|
50
|
+
return 0 if resource(statement) == ['*'] || action(statement) == ['*']
|
51
|
+
|
52
|
+
resource_service_names = resource(statement).map { |resource_arn| resource_service_name(resource_arn) }
|
53
|
+
action_service_names = action(statement).map { |action| action_service_name(action) }
|
54
|
+
|
55
|
+
(set_without_wildcard(resource_service_names) - set_without_wildcard(action_service_names)).size
|
56
|
+
end
|
57
|
+
|
58
|
+
# rubocop:disable Naming/AccessorMethodName
|
59
|
+
def set_without_wildcard(array)
|
60
|
+
Set.new(array).delete('*')
|
61
|
+
end
|
62
|
+
# rubocop:enable Naming/AccessorMethodName
|
63
|
+
|
64
|
+
def extra_service_count(statement)
|
65
|
+
service_names = Set.new(action_service_names(statement) + resource_service_names(statement)).delete('*')
|
66
|
+
[service_names.size - 1, 0].max
|
67
|
+
end
|
68
|
+
|
69
|
+
def action_service_names(statement)
|
70
|
+
action(statement).map { |action| action_service_name(action) }
|
71
|
+
end
|
72
|
+
|
73
|
+
def resource_service_names(statement)
|
74
|
+
resource(statement).map { |resource_arn| resource_service_name(resource_arn) }
|
75
|
+
end
|
76
|
+
|
77
|
+
def action_service_name(action)
|
78
|
+
return '*' if action == '*'
|
79
|
+
|
80
|
+
return action unless action.is_a?(String)
|
81
|
+
|
82
|
+
action.split(':')[0]
|
83
|
+
end
|
84
|
+
|
85
|
+
def resource_service_name(resource_arn)
|
86
|
+
return '*' if resource_arn == '*'
|
87
|
+
|
88
|
+
return resource_arn unless resource_arn.is_a?(String)
|
89
|
+
|
90
|
+
resource_arn.split(':')[2]
|
91
|
+
end
|
92
|
+
|
93
|
+
def action(statement)
|
94
|
+
return statement.actions unless statement.actions.empty?
|
95
|
+
|
96
|
+
statement.not_actions
|
97
|
+
end
|
98
|
+
|
99
|
+
def resource(statement)
|
100
|
+
return statement.resources unless statement.resources.empty?
|
101
|
+
|
102
|
+
statement.not_resources
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Weights
|
4
|
+
def weights
|
5
|
+
{
|
6
|
+
Base_Statement: 1,
|
7
|
+
Allow: 0,
|
8
|
+
Deny: 1,
|
9
|
+
NotAction: 1,
|
10
|
+
NotResource: 1,
|
11
|
+
Mixed_Wildcard: 1,
|
12
|
+
|
13
|
+
Extra_Service: 2,
|
14
|
+
Resource_Action_NotAligned: 1,
|
15
|
+
|
16
|
+
Condition: 2,
|
17
|
+
IfExists: 1,
|
18
|
+
Null: 1,
|
19
|
+
PolicyVariables: 1
|
20
|
+
}
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'cfn-model'
|
4
|
+
|
5
|
+
##
|
6
|
+
# Mix-in with metadata handling routines for the CustomRuleLoader
|
7
|
+
module Metadata
|
8
|
+
# XXX given mangled_metadatas is never used or returned,
|
9
|
+
# STDERR emit can be moved to unless block
|
10
|
+
def validate_cfn_nag_metadata(cfn_model)
|
11
|
+
mangled_metadatas = collect_mangled_metadata(cfn_model)
|
12
|
+
mangled_metadatas.each do |mangled_metadata|
|
13
|
+
logical_resource_id = mangled_metadata.first
|
14
|
+
mangled_rules = mangled_metadata[1]
|
15
|
+
|
16
|
+
STDERR.puts "#{logical_resource_id} has missing cfn_nag suppression rule id: #{mangled_rules}"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def cfn_model_with_suppressed_resources_removed(cfn_model:,
|
21
|
+
rule_id:,
|
22
|
+
allow_suppression:,
|
23
|
+
print_suppression:)
|
24
|
+
return cfn_model unless allow_suppression
|
25
|
+
|
26
|
+
cfn_model = cfn_model.copy
|
27
|
+
|
28
|
+
cfn_model.resources.delete_if do |logical_resource_id, resource|
|
29
|
+
rules_to_suppress = rules_to_suppress resource
|
30
|
+
if rules_to_suppress.nil?
|
31
|
+
false
|
32
|
+
else
|
33
|
+
suppress_resource?(rules_to_suppress, rule_id, logical_resource_id, print_suppression)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
cfn_model
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def suppress_resource?(rules_to_suppress, rule_id, logical_resource_id, print_suppression)
|
42
|
+
found_suppression_rule = rules_to_suppress.find do |rule_to_suppress|
|
43
|
+
next if rule_to_suppress['id'].nil?
|
44
|
+
|
45
|
+
rule_to_suppress['id'] == rule_id
|
46
|
+
end
|
47
|
+
if found_suppression_rule && print_suppression
|
48
|
+
message = "Suppressing #{rule_id} on #{logical_resource_id} for reason: #{found_suppression_rule['reason']}"
|
49
|
+
STDERR.puts message
|
50
|
+
end
|
51
|
+
!found_suppression_rule.nil?
|
52
|
+
end
|
53
|
+
|
54
|
+
def rules_to_suppress(resource)
|
55
|
+
if resource.metadata &&
|
56
|
+
resource.metadata['cfn_nag'] &&
|
57
|
+
resource.metadata['cfn_nag']['rules_to_suppress']
|
58
|
+
|
59
|
+
resource.metadata['cfn_nag']['rules_to_suppress']
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def collect_mangled_metadata(cfn_model)
|
64
|
+
mangled_metadatas = []
|
65
|
+
cfn_model.resources.each do |logical_resource_id, resource|
|
66
|
+
resource_rules_to_suppress = rules_to_suppress resource
|
67
|
+
next if resource_rules_to_suppress.nil?
|
68
|
+
|
69
|
+
mangled_rules = resource_rules_to_suppress.select do |rule_to_suppress|
|
70
|
+
rule_to_suppress['id'].nil?
|
71
|
+
end
|
72
|
+
unless mangled_rules.empty?
|
73
|
+
mangled_metadatas << [logical_resource_id, mangled_rules]
|
74
|
+
end
|
75
|
+
end
|
76
|
+
mangled_metadatas
|
77
|
+
end
|
78
|
+
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.
|
4
|
+
version: 0.6.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Eric Kascic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-06-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -72,14 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - '='
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version: 0.5.
|
75
|
+
version: 0.5.1
|
76
76
|
type: :runtime
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - '='
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version: 0.5.
|
82
|
+
version: 0.5.1
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: logging
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -156,12 +156,14 @@ executables:
|
|
156
156
|
- cfn_nag
|
157
157
|
- cfn_nag_rules
|
158
158
|
- cfn_nag_scan
|
159
|
+
- spcm_scan
|
159
160
|
extensions: []
|
160
161
|
extra_rdoc_files: []
|
161
162
|
files:
|
162
163
|
- bin/cfn_nag
|
163
164
|
- bin/cfn_nag_rules
|
164
165
|
- bin/cfn_nag_scan
|
166
|
+
- bin/spcm_scan
|
165
167
|
- lib/cfn-nag.rb
|
166
168
|
- lib/cfn-nag/base_rule.rb
|
167
169
|
- lib/cfn-nag/blacklist_loader.rb
|
@@ -295,6 +297,7 @@ files:
|
|
295
297
|
- lib/cfn-nag/custom_rules/S3BucketPolicyWildcardPrincipalRule.rb
|
296
298
|
- lib/cfn-nag/custom_rules/S3BucketPublicReadAclRule.rb
|
297
299
|
- lib/cfn-nag/custom_rules/S3BucketPublicReadWriteAclRule.rb
|
300
|
+
- lib/cfn-nag/custom_rules/SPCMRule.rb
|
298
301
|
- lib/cfn-nag/custom_rules/SageMakerEndpointConfigKmsKeyIdRule.rb
|
299
302
|
- lib/cfn-nag/custom_rules/SageMakerNotebookInstanceKmsKeyIdRule.rb
|
300
303
|
- lib/cfn-nag/custom_rules/SecretsManagerSecretKmsKeyIdRule.rb
|
@@ -327,7 +330,14 @@ files:
|
|
327
330
|
- lib/cfn-nag/custom_rules/password_base_rule.rb
|
328
331
|
- lib/cfn-nag/custom_rules/resource_base_rule.rb
|
329
332
|
- lib/cfn-nag/custom_rules/sub_property_with_list_password_base_rule.rb
|
333
|
+
- lib/cfn-nag/iam_complexity_metric/condition_metric.rb
|
334
|
+
- lib/cfn-nag/iam_complexity_metric/html_results_renderer.rb
|
335
|
+
- lib/cfn-nag/iam_complexity_metric/policy_document_metric.rb
|
336
|
+
- lib/cfn-nag/iam_complexity_metric/spcm.rb
|
337
|
+
- lib/cfn-nag/iam_complexity_metric/statement_metric.rb
|
338
|
+
- lib/cfn-nag/iam_complexity_metric/weights.rb
|
330
339
|
- lib/cfn-nag/ip_addr.rb
|
340
|
+
- lib/cfn-nag/metadata.rb
|
331
341
|
- lib/cfn-nag/profile_loader.rb
|
332
342
|
- lib/cfn-nag/result_view/colored_stdout_results.rb
|
333
343
|
- lib/cfn-nag/result_view/json_results.rb
|
@@ -371,7 +381,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
371
381
|
- !ruby/object:Gem::Version
|
372
382
|
version: '0'
|
373
383
|
requirements: []
|
374
|
-
rubygems_version: 3.1.
|
384
|
+
rubygems_version: 3.1.3
|
375
385
|
signing_key:
|
376
386
|
specification_version: 4
|
377
387
|
summary: cfn-nag
|