cfn-nag 0.6.5 → 0.6.10

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fcec15f2d25123e50039b0618dbd0da02e2e798ade4b35fea7abb3f6e9035eba
4
- data.tar.gz: 8eeea21427d600ce45addb7ebe595ddeeeec469b6ebf8fe7fde1f62685ad4b83
3
+ metadata.gz: abfc80557991b6243d7324acf49f7f86d878a9a076e9760bd42eab6af5a02132
4
+ data.tar.gz: 28516fe4a3ee488d6608f85a4e4d00d30cd09464e5515b6e7da05b0c2ece771d
5
5
  SHA512:
6
- metadata.gz: b242c9866270499f2e1b87594043813dd6078ab7cea40eaaa6fff6835a48405c3645a1895e8e6630d1d04c337fbfb90d6a6b7c168cbffd97df8339076aec69dd
7
- data.tar.gz: 02ec8b6dfc2b4409bffb5f9339e41e59a79f076b6d288d74d9752e1357ad9918acc0360ba07fa3017c633951c47ee238a6f6ad0a4deca7b61c7d43109c6e023e
6
+ metadata.gz: c59247c40157d4f5af73a09ed733e72b26e8a9d5e79e61f304bbbf91b8bba3562a2176a5c0d411755a31f98aef012500ca78e29a8546a0c4a2795e12257cae3e
7
+ data.tar.gz: 8f343d1a16de3fe03385a757c5b30f4944a70b7223ce116950d7fd4d95fa1f8ac55ea9a7b550d8a36c4de1aa05e05c9fae3f0cc88af1e45514185f0e9dba844f
@@ -18,79 +18,80 @@ class EC2NetworkAclEntryOverlappingPortsRule < BaseRule
18
18
  end
19
19
 
20
20
  def audit_impl(cfn_model)
21
+ nacl_entries = cfn_model.resources_by_type('AWS::EC2::NetworkAclEntry')
22
+
23
+ # Select nacl entries that can be evaluated
24
+ nacl_entries.select! do |nacl_entry|
25
+ tcp_or_udp_protocol?(nacl_entry) && valid_ports?(nacl_entry)
26
+ end
27
+
21
28
  violating_nacl_entries = []
22
- cfn_model.resources_by_type('AWS::EC2::NetworkAcl').each do |nacl|
23
- violating_nacl_entries += violating_nacl_entries(nacl)
29
+
30
+ # Group entries by nacl id, ip type, and egress/ingress
31
+ grouped_nacl_entries = group_nacl_entries(nacl_entries)
32
+
33
+ grouped_nacl_entries.each do |grouping|
34
+ violating_nacl_entries += overlapping_port_entries(grouping)
24
35
  end
25
36
  violating_nacl_entries.map(&:logical_resource_id)
26
37
  end
27
38
 
28
39
  private
29
40
 
30
- def overlapping_port_entries(nacl_entries)
31
- unique_pairs(nacl_entries).select do |nacl_entry_pair|
32
- tcp_or_udp_protocol?(nacl_entry_pair[0], nacl_entry_pair[1]) && overlap?(nacl_entry_pair[0], nacl_entry_pair[1])
33
- end
41
+ def tcp_or_udp_protocol?(entry)
42
+ %w[6 17].include?(entry.protocol.to_s)
34
43
  end
35
44
 
36
- def tcp_or_udp_protocol?(entry1, entry2)
37
- %w[6 17].include?(entry1.protocol.to_s) && %w[6 17].include?(entry2.protocol.to_s)
45
+ def valid_ports?(entry)
46
+ !entry.portRange.nil? && valid_port_number?(entry.portRange['From']) && valid_port_number?(entry.portRange['To'])
38
47
  end
39
48
 
40
- def unique_pairs(arr)
41
- pairs_without_dupes = arr.product(arr).select { |pair| pair[0] != pair[1] }
42
- pairs_without_dupes.reduce(Set.new) { |set_of_sets, pair| set_of_sets << Set.new(pair) }.to_a.map(&:to_a)
49
+ def valid_port_number?(port)
50
+ port.is_a?(Numeric) || (port.is_a?(String) && port.to_i(10) != 0)
43
51
  end
44
52
 
45
- def overlap?(entry1, entry2)
46
- roverlap?(entry1, entry2) || loverlap?(entry1, entry2)
47
- end
53
+ def group_nacl_entries(nacl_entries)
54
+ grouped_nacl_entries = []
48
55
 
49
- def roverlap?(entry1, entry2)
50
- entry1.portRange['From'].between?(entry2.portRange['From'], entry2.portRange['To']) ||
51
- entry1.portRange['To'].between?(entry2.portRange['From'], entry2.portRange['To'])
52
- end
56
+ # Group by NaclID
57
+ nacl_entries.group_by(&:networkAclId).each_value do |entries|
58
+ # Split entries by ip type
59
+ ipv4_entries, ipv6_entries = entries.partition { |nacl_entry| nacl_entry.ipv6CidrBlock.nil? }
53
60
 
54
- def loverlap?(entry1, entry2)
55
- entry2.portRange['From'].between?(entry1.portRange['From'], entry1.portRange['To']) ||
56
- entry2.portRange['To'].between?(entry1.portRange['From'], entry1.portRange['To'])
57
- end
61
+ # Split entries by egress/ingress
62
+ egress4, ingress4 = ipv4_entries.partition { |nacl_entry| truthy?(nacl_entry.egress) }
63
+ egress6, ingress6 = ipv6_entries.partition { |nacl_entry| truthy?(nacl_entry.egress) }
58
64
 
59
- def egress_entries(nacl_entries)
60
- nacl_entries.select do |nacl_entry|
61
- truthy?(nacl_entry.egress)
65
+ grouped_nacl_entries << egress4
66
+ grouped_nacl_entries << ingress4
67
+ grouped_nacl_entries << egress6
68
+ grouped_nacl_entries << ingress6
62
69
  end
63
- end
64
70
 
65
- def ingress_entries(nacl_entries)
66
- nacl_entries.select do |nacl_entry|
67
- not_truthy?(nacl_entry.egress)
68
- end
71
+ grouped_nacl_entries
69
72
  end
70
73
 
71
- def ip6_entries(nacl_entries)
72
- nacl_entries.select do |nacl_entry|
73
- !nacl_entry.ipv6CidrBlock.nil?
74
- end
74
+ def overlapping_port_entries(nacl_entries)
75
+ unique_pairs(nacl_entries).select do |nacl_entry_pair|
76
+ overlap?(nacl_entry_pair[0], nacl_entry_pair[1])
77
+ end.flatten.uniq
75
78
  end
76
79
 
77
- def ip4_entries(nacl_entries)
78
- nacl_entries.select do |nacl_entry|
79
- nacl_entry.ipv6CidrBlock.nil?
80
- end
80
+ def unique_pairs(arr)
81
+ pairs_without_dupes = arr.product(arr).select { |pair| pair[0] != pair[1] }
82
+ pairs_without_dupes.reduce(Set.new) { |set_of_sets, pair| set_of_sets << Set.new(pair) }.to_a.map(&:to_a)
81
83
  end
82
84
 
83
- def violating_nacl_entries(nacl)
84
- violating_ip4_nacl_entries(nacl) || violating_ip6_nacl_entries(nacl)
85
+ def overlap?(entry1, entry2)
86
+ port_overlap?(entry1.portRange, entry2.portRange) || port_overlap?(entry2.portRange, entry1.portRange)
85
87
  end
86
88
 
87
- def violating_ip4_nacl_entries(nacl)
88
- overlapping_port_entries(egress_entries(ip4_entries(nacl.network_acl_entries))).flatten.uniq &&
89
- overlapping_port_entries(ingress_entries(ip4_entries(nacl.network_acl_entries))).flatten.uniq
89
+ def port_overlap?(port_range1, port_range2)
90
+ port_number(port_range1['From']).between?(port_number(port_range2['From']), port_number(port_range2['To'])) ||
91
+ port_number(port_range1['To']).between?(port_number(port_range2['From']), port_number(port_range2['To']))
90
92
  end
91
93
 
92
- def violating_ip6_nacl_entries(nacl)
93
- overlapping_port_entries(egress_entries(ip6_entries(nacl.network_acl_entries))).flatten.uniq &&
94
- overlapping_port_entries(ingress_entries(ip6_entries(nacl.network_acl_entries))).flatten.uniq
94
+ def port_number(port)
95
+ port.to_i
95
96
  end
96
97
  end
@@ -26,7 +26,10 @@ class SPCMRule < BaseRule
26
26
  policy_documents = SPCM.new.metric_impl(cfn_model)
27
27
  rescue StandardError => catch_all_exception
28
28
  puts "Experimental SPCM rule is failing. Please report #{catch_all_exception} with the violating template"
29
- policy_documents = {}
29
+ policy_documents = {
30
+ 'AWS::IAM::Policy' => {},
31
+ 'AWS::IAM::Role' => {}
32
+ }
30
33
  end
31
34
 
32
35
  threshold = spcm_threshold.nil? ? DEFAULT_THRESHOLD : spcm_threshold.to_i
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.6.5
4
+ version: 0.6.10
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-06-02 00:00:00.000000000 Z
11
+ date: 2020-10-12 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.1
75
+ version: 0.5.2
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.1
82
+ version: 0.5.2
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: logging
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -128,14 +128,14 @@ dependencies:
128
128
  requirements:
129
129
  - - "~>"
130
130
  - !ruby/object:Gem::Version
131
- version: 1.60.1
131
+ version: '1.76'
132
132
  type: :runtime
133
133
  prerelease: false
134
134
  version_requirements: !ruby/object:Gem::Requirement
135
135
  requirements:
136
136
  - - "~>"
137
137
  - !ruby/object:Gem::Version
138
- version: 1.60.1
138
+ version: '1.76'
139
139
  - !ruby/object:Gem::Dependency
140
140
  name: lightly
141
141
  requirement: !ruby/object:Gem::Requirement
@@ -381,7 +381,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
381
381
  - !ruby/object:Gem::Version
382
382
  version: '0'
383
383
  requirements: []
384
- rubygems_version: 3.1.3
384
+ rubygems_version: 3.1.4
385
385
  signing_key:
386
386
  specification_version: 4
387
387
  summary: cfn-nag