heimdall_tools 1.3.40 → 1.3.41

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.
@@ -6,7 +6,7 @@ require 'nokogiri'
6
6
 
7
7
  RESOURCE_DIR = Pathname.new(__FILE__).join('../../data')
8
8
 
9
- NESSUS_PLUGINS_NIST_MAPPING_FILE = File.join(RESOURCE_DIR, 'nessus-plugins-nist-mapping.csv')
9
+ NESSUS_PLUGINS_NIST_MAPPING_FILE = File.join(RESOURCE_DIR, 'nessus-plugins-nist-mapping.csv')
10
10
  U_CCI_LIST = File.join(RESOURCE_DIR, 'U_CCI_List.xml')
11
11
 
12
12
  IMPACT_MAPPING = {
@@ -14,16 +14,16 @@ IMPACT_MAPPING = {
14
14
  Low: 0.3,
15
15
  Medium: 0.5,
16
16
  High: 0.7,
17
- Critical: 0.9,
17
+ Critical: 0.9
18
18
  }.freeze
19
19
 
20
- DEFAULT_NIST_TAG = ["unmapped"].freeze
20
+ DEFAULT_NIST_TAG = ['unmapped'].freeze
21
21
 
22
22
  # Nessus results file 800-53 refs does not contain Nist rev version. Using this default
23
23
  # version in that case
24
24
  DEFAULT_NIST_REV = 'Rev_4'.freeze
25
25
 
26
- NA_PLUGIN_OUTPUT = "This Nessus Plugin does not provide output message.".freeze
26
+ NA_PLUGIN_OUTPUT = 'This Nessus Plugin does not provide output message.'.freeze
27
27
 
28
28
  # rubocop:disable Metrics/AbcSize
29
29
 
@@ -51,19 +51,16 @@ module HeimdallTools
51
51
  rescue StandardError => e
52
52
  raise "Invalid Nessus XML file provided Exception: #{e}"
53
53
  end
54
-
55
54
  end
56
55
 
57
56
  def extract_report
58
- begin
59
- # When there are multiple hosts in the nessus report ReportHost field is an array
60
- # When there is only one host in the nessus report ReportHost field is a hash
61
- # Array() converts ReportHost to array in case there is only one host
62
- reports = @data['NessusClientData_v2']['Report']['ReportHost']
63
- reports.kind_of?(Array) ? reports : [reports]
64
- rescue StandardError => e
65
- raise "Invalid Nessus XML file provided Exception: #{e}"
66
- end
57
+ # When there are multiple hosts in the nessus report ReportHost field is an array
58
+ # When there is only one host in the nessus report ReportHost field is a hash
59
+ # Array() converts ReportHost to array in case there is only one host
60
+ reports = @data['NessusClientData_v2']['Report']['ReportHost']
61
+ reports.is_a?(Array) ? reports : [reports]
62
+ rescue StandardError => e
63
+ raise "Invalid Nessus XML file provided Exception: #{e}"
67
64
  end
68
65
 
69
66
  def parse_refs(refs, key)
@@ -71,24 +68,20 @@ module HeimdallTools
71
68
  end
72
69
 
73
70
  def extract_scaninfo
74
- begin
75
- policy = @data['NessusClientData_v2']['Policy']
76
- info = {}
71
+ policy = @data['NessusClientData_v2']['Policy']
72
+ info = {}
77
73
 
78
- info['policyName'] = policy['policyName']
79
- info['version'] = policy['Preferences']['ServerPreferences']['preference'].select {|x| x['name'].eql? 'sc_version'}.first['value']
80
- info
81
- rescue StandardError => e
82
- raise "Invalid Nessus XML file provided Exception: #{e}"
83
- end
74
+ info['policyName'] = policy['policyName']
75
+ info['version'] = policy['Preferences']['ServerPreferences']['preference'].select { |x| x['name'].eql? 'sc_version' }.first['value']
76
+ info
77
+ rescue StandardError => e
78
+ raise "Invalid Nessus XML file provided Exception: #{e}"
84
79
  end
85
80
 
86
81
  def extract_timestamp(report)
87
- begin
88
- timestamp = report['HostProperties']['tag'].select {|x| x['name'].eql? 'HOST_START'}.first['text']
89
- rescue StandardError => e
90
- raise "Invalid Nessus XML file provided Exception: #{e}"
91
- end
82
+ report['HostProperties']['tag'].select { |x| x['name'].eql? 'HOST_START' }.first['text']
83
+ rescue StandardError => e
84
+ raise "Invalid Nessus XML file provided Exception: #{e}"
92
85
  end
93
86
 
94
87
  def format_desc(issue)
@@ -129,7 +122,7 @@ module HeimdallTools
129
122
 
130
123
  def cci_nist_tag(cci_refs)
131
124
  nist_tags = []
132
- cci_refs.each do | cci_ref |
125
+ cci_refs.each do |cci_ref|
133
126
  item_node = @cci_xml.xpath("//cci_list/cci_items/cci_item[@id='#{cci_ref}']")[0] unless @cci_xml.nil?
134
127
  unless item_node.nil?
135
128
  nist_ref = item_node.xpath('./references/reference[not(@version <= preceding-sibling::reference/@version) and not(@version <=following-sibling::reference/@version)]/@index').text
@@ -140,7 +133,7 @@ module HeimdallTools
140
133
  end
141
134
 
142
135
  def plugin_nist_tag(pluginfamily, pluginid)
143
- entries = @cwe_nist_mapping.select { |x| (x[:pluginfamily].eql?(pluginfamily) && (x[:pluginid].eql?('*') || x[:pluginid].eql?(pluginid.to_i)) ) && !x[:nistid].nil? }
136
+ entries = @cwe_nist_mapping.select { |x| (x[:pluginfamily].eql?(pluginfamily) && (x[:pluginid].eql?('*') || x[:pluginid].eql?(pluginid.to_i))) && !x[:nistid].nil? }
144
137
  tags = entries.map { |x| [x[:nistid].split('|'), "Rev_#{x[:rev]}"] }
145
138
  tags.empty? ? DEFAULT_NIST_TAG : tags.flatten.uniq
146
139
  end
@@ -148,15 +141,15 @@ module HeimdallTools
148
141
  def impact(severity)
149
142
  # Map CAT levels and Plugin severity to HDF impact levels
150
143
  case severity
151
- when "0"
144
+ when '0'
152
145
  IMPACT_MAPPING[:Info]
153
- when "1","III"
146
+ when '1', 'III'
154
147
  IMPACT_MAPPING[:Low]
155
- when "2","II"
148
+ when '2', 'II'
156
149
  IMPACT_MAPPING[:Medium]
157
- when "3","I"
150
+ when '3', 'I'
158
151
  IMPACT_MAPPING[:High]
159
- when "4"
152
+ when '4'
160
153
  IMPACT_MAPPING[:Critical]
161
154
  else
162
155
  -1
@@ -172,17 +165,17 @@ module HeimdallTools
172
165
  end
173
166
 
174
167
  def desc_tags(data, label)
175
- { "data": data || NA_STRING, "label": label || NA_STRING }
168
+ { data: data || NA_STRING, label: label || NA_STRING }
176
169
  end
177
170
 
178
171
  # Nessus report could have multiple issue entries for multiple findings of same issue type.
179
- # The meta data is identical across entries
172
+ # The meta data is identical across entries
180
173
  # method collapse_duplicates return unique controls with applicable findings collapsed into it.
181
174
  def collapse_duplicates(controls)
182
175
  unique_controls = []
183
176
 
184
177
  controls.map { |x| x['id'] }.uniq.each do |id|
185
- collapsed_results = controls.select { |x| x['id'].eql?(id) }.map {|x| x['results']}
178
+ collapsed_results = controls.select { |x| x['id'].eql?(id) }.map { |x| x['results'] }
186
179
  unique_control = controls.find { |x| x['id'].eql?(id) }
187
180
  unique_control['results'] = collapsed_results.flatten
188
181
  unique_controls << unique_control
@@ -192,9 +185,9 @@ module HeimdallTools
192
185
 
193
186
  def to_hdf
194
187
  host_results = {}
195
- @reports.each do | report|
188
+ @reports.each do |report|
196
189
  controls = []
197
- report['ReportItem'].each do | item |
190
+ report['ReportItem'].each do |item|
198
191
  printf("\rProcessing: %s", $spinner.next)
199
192
  @item = {}
200
193
  @item['tags'] = {}
@@ -207,7 +200,7 @@ module HeimdallTools
207
200
  # Current version covers STIG based 'Policy Compliance' results
208
201
  # TODO Cover cases for 'Policy Compliance' results based on CIS
209
202
  if item['compliance-reference']
210
- @item['id'] = parse_refs(item['compliance-reference'],'Vuln-ID').join.to_s
203
+ @item['id'] = parse_refs(item['compliance-reference'], 'Vuln-ID').join.to_s
211
204
  else
212
205
  @item['id'] = item['pluginID'].to_s
213
206
  end
@@ -222,17 +215,17 @@ module HeimdallTools
222
215
  @item['desc'] = format_desc(item).to_s
223
216
  end
224
217
  if item['compliance-reference']
225
- @item['impact'] = impact(parse_refs(item['compliance-reference'],'CAT').join.to_s)
218
+ @item['impact'] = impact(parse_refs(item['compliance-reference'], 'CAT').join.to_s)
226
219
  else
227
- @item['impact'] = impact(item['severity'])
220
+ @item['impact'] = impact(item['severity'])
228
221
  end
229
222
  if item['compliance-reference']
230
- @item['tags']['nist'] = cci_nist_tag(parse_refs(item['compliance-reference'],'CCI'))
223
+ @item['tags']['nist'] = cci_nist_tag(parse_refs(item['compliance-reference'], 'CCI'))
231
224
  else
232
- @item['tags']['nist'] = plugin_nist_tag(item['pluginFamily'],item['pluginID'])
225
+ @item['tags']['nist'] = plugin_nist_tag(item['pluginFamily'], item['pluginID'])
233
226
  end
234
227
  if item['compliance-solution']
235
- @item['descriptions'] << desc_tags(item['compliance-solution'], 'check')
228
+ @item['descriptions'] << desc_tags(item['compliance-solution'], 'check')
236
229
  end
237
230
 
238
231
  @item['code'] = ''
@@ -17,13 +17,11 @@ IMPACT_MAPPING = {
17
17
  Information: 0.0
18
18
  }.freeze
19
19
 
20
- DEFAULT_NIST_TAG = ["SA-11", "RA-5"].freeze
21
-
22
- # rubocop:disable Metrics/AbcSize
20
+ DEFAULT_NIST_TAG = %w{SA-11 RA-5}.freeze
23
21
 
24
22
  module HeimdallTools
25
23
  class NetsparkerMapper
26
- def initialize(xml, name=nil, verbose = false)
24
+ def initialize(xml, _name = nil, verbose = false)
27
25
  @verbose = verbose
28
26
 
29
27
  begin
@@ -33,7 +31,6 @@ module HeimdallTools
33
31
 
34
32
  @vulnerabilities = data['netsparker-enterprise']['vulnerabilities']['vulnerability']
35
33
  @scan_info = data['netsparker-enterprise']['target']
36
-
37
34
  rescue StandardError => e
38
35
  raise "Invalid Netsparker XML file provided Exception: #{e}"
39
36
  end
@@ -63,7 +60,7 @@ module HeimdallTools
63
60
  controls = collapse_duplicates(controls)
64
61
  results = HeimdallDataFormat.new(profile_name: 'Netsparker Enterprise Scan',
65
62
  title: "Netsparker Enterprise Scan ID: #{@scan_info['scan-id']} URL: #{@scan_info['url']}",
66
- summary: "Netsparker Enterprise Scan",
63
+ summary: 'Netsparker Enterprise Scan',
67
64
  target_id: @scan_info['url'],
68
65
  controls: controls)
69
66
  results.to_hdf
@@ -79,25 +76,25 @@ module HeimdallTools
79
76
  finding = {}
80
77
  finding['status'] = 'failed'
81
78
  finding['code_desc'] = []
82
- finding['code_desc'] << "http-request : #{parse_html(vulnerability['http-request']['content']) }"
79
+ finding['code_desc'] << "http-request : #{parse_html(vulnerability['http-request']['content'])}"
83
80
  finding['code_desc'] << "method : #{vulnerability['http-request']['method']}"
84
81
  finding['code_desc'] = finding['code_desc'].join("\n")
85
82
 
86
83
  finding['message'] = []
87
- finding['message'] << "http-response : #{parse_html(vulnerability['http-response']['content']) }"
84
+ finding['message'] << "http-response : #{parse_html(vulnerability['http-response']['content'])}"
88
85
  finding['message'] << "duration : #{vulnerability['http-response']['duration']}"
89
86
  finding['message'] << "status-code : #{vulnerability['http-response']['status-code']}"
90
87
  finding['message'] = finding['message'].join("\n")
91
88
  finding['run_time'] = NA_FLOAT
92
89
 
93
- finding['start_time'] = @scan_info['initiated']
90
+ finding['start_time'] = @scan_info['initiated']
94
91
  [finding]
95
92
  end
96
93
 
97
94
  def format_control_desc(vulnerability)
98
95
  text = []
99
- text << "#{parse_html(vulnerability['description'])}" unless vulnerability['description'].nil?
100
- text << "Exploitation-skills: #{parse_html(vulnerability['exploitation-skills'])}" unless vulnerability['exploitation-skills'].nil?
96
+ text << parse_html(vulnerability['description']).to_s unless vulnerability['description'].nil?
97
+ text << "Exploitation-skills: #{parse_html(vulnerability['exploitation-skills'])}" unless vulnerability['exploitation-skills'].nil?
101
98
  text << "Extra-information: #{vulnerability['extra-information']}" unless vulnerability['extra-information'].nil?
102
99
  text << "Classification: #{vulnerability['classification']}" unless vulnerability['classification'].nil?
103
100
  text << "Impact: #{parse_html(vulnerability['impact'])}" unless vulnerability['impact'].nil?
@@ -106,14 +103,14 @@ module HeimdallTools
106
103
  text << "Certainty: #{vulnerability['certainty']}" unless vulnerability['certainty'].nil?
107
104
  text << "Type: #{vulnerability['type']}" unless vulnerability['type'].nil?
108
105
  text << "Confirmed: #{vulnerability['confirmed']}" unless vulnerability['confirmed'].nil?
109
- text.join("<br>")
106
+ text.join('<br>')
110
107
  end
111
108
 
112
109
  def format_check_text(vulnerability)
113
110
  text = []
114
111
  text << "Exploitation-skills: #{parse_html(vulnerability['exploitation-skills'])}" unless vulnerability['exploitation-skills'].nil?
115
112
  text << "Proof-of-concept: #{parse_html(vulnerability['proof-of-concept'])}" unless vulnerability['proof-of-concept'].nil?
116
- text.join("<br>")
113
+ text.join('<br>')
117
114
  end
118
115
 
119
116
  def format_fix_text(vulnerability)
@@ -121,7 +118,7 @@ module HeimdallTools
121
118
  text << "Remedial-actions: #{parse_html(vulnerability['remedial-actions'])}" unless vulnerability['remedial-actions'].nil?
122
119
  text << "Remedial-procedure: #{parse_html(vulnerability['remedial-procedure'])}" unless vulnerability['remedial-procedure'].nil?
123
120
  text << "Remedy-references: #{parse_html(vulnerability['remedy-references'])}" unless vulnerability['remedy-references'].nil?
124
- text.join("<br>")
121
+ text.join('<br>')
125
122
  end
126
123
 
127
124
  def nist_tag(classification)
@@ -146,7 +143,7 @@ module HeimdallTools
146
143
  end
147
144
 
148
145
  def desc_tags(data, label)
149
- { "data": data || NA_STRING, "label": label || NA_STRING }
146
+ { data: data || NA_STRING, label: label || NA_STRING }
150
147
  end
151
148
 
152
149
  # Netsparker report could have multiple issue entries for multiple findings of same issue type.
@@ -156,7 +153,7 @@ module HeimdallTools
156
153
  unique_controls = []
157
154
 
158
155
  controls.map { |x| x['id'] }.uniq.each do |id|
159
- collapsed_results = controls.select { |x| x['id'].eql?(id) }.map {|x| x['results']}
156
+ collapsed_results = controls.select { |x| x['id'].eql?(id) }.map { |x| x['results'] }
160
157
  unique_control = controls.find { |x| x['id'].eql?(id) }
161
158
  unique_control['results'] = collapsed_results.flatten
162
159
  unique_controls << unique_control
@@ -9,10 +9,10 @@ NIKTO_NIST_MAPPING_FILE = File.join(RESOURCE_DIR, 'nikto-nist-mapping.csv')
9
9
  IMPACT_MAPPING = {
10
10
  high: 0.7,
11
11
  medium: 0.5,
12
- low: 0.3,
12
+ low: 0.3
13
13
  }.freeze
14
14
 
15
- DEFAULT_NIST_TAG = ["SA-11", "RA-5"].freeze
15
+ DEFAULT_NIST_TAG = %w{SA-11 RA-5}.freeze
16
16
 
17
17
  # Loading spinner sign
18
18
  $spinner = Enumerator.new do |e|
@@ -26,7 +26,7 @@ end
26
26
 
27
27
  module HeimdallTools
28
28
  class NiktoMapper
29
- def initialize(nikto_json, name=nil, verbose = false)
29
+ def initialize(nikto_json, _name = nil, verbose = false)
30
30
  @nikto_json = nikto_json
31
31
  @verbose = verbose
32
32
 
@@ -36,9 +36,9 @@ module HeimdallTools
36
36
  raise "Invalid Nikto to NIST mapping file: Exception: #{e}"
37
37
  end
38
38
 
39
- # TODO: Support Multi-target scan results
40
- # Nikto multi-target scans generate invalid format JSONs
41
- # Possible workaround to use https://stackoverflow.com/a/58209963/1670307
39
+ # TODO: Support Multi-target scan results
40
+ # Nikto multi-target scans generate invalid format JSONs
41
+ # Possible workaround to use https://stackoverflow.com/a/58209963/1670307
42
42
 
43
43
  begin
44
44
  @project = JSON.parse(nikto_json)
@@ -64,7 +64,7 @@ module HeimdallTools
64
64
  def finding(vulnerability)
65
65
  finding = {}
66
66
  finding['status'] = 'failed'
67
- finding['code_desc'] = "URL : #{vulnerability['url'].to_s } Method: #{vulnerability['method'].to_s}"
67
+ finding['code_desc'] = "URL : #{vulnerability['url']} Method: #{vulnerability['method']}"
68
68
  finding['run_time'] = NA_FLOAT
69
69
  finding['start_time'] = NA_STRING
70
70
  [finding]
@@ -83,32 +83,32 @@ module HeimdallTools
83
83
  def parse_mapper
84
84
  csv_data = CSV.read(NIKTO_NIST_MAPPING_FILE, **{ encoding: 'UTF-8',
85
85
  headers: true,
86
- header_converters: :symbol})
86
+ header_converters: :symbol })
87
87
  csv_data.map(&:to_hash)
88
88
  end
89
89
 
90
90
  def desc_tags(data, label)
91
- { "data": data || NA_STRING, "label": label || NA_STRING }
91
+ { data: data || NA_STRING, label: label || NA_STRING }
92
92
  end
93
93
 
94
- # Nikto report could have multiple vulnerability entries for multiple findings of same issue type.
95
- # The meta data is identical across entries
96
- # method collapse_duplicates return unique controls with applicable findings collapsed into it.
97
- def collapse_duplicates(controls)
98
- unique_controls = []
99
-
100
- controls.map { |x| x['id'] }.uniq.each do |id|
101
- collapsed_results = controls.select { |x| x['id'].eql?(id) }.map {|x| x['results']}
102
- unique_control = controls.find { |x| x['id'].eql?(id) }
103
- unique_control['results'] = collapsed_results.flatten
104
- unique_controls << unique_control
105
- end
106
- unique_controls
107
- end
94
+ # Nikto report could have multiple vulnerability entries for multiple findings of same issue type.
95
+ # The meta data is identical across entries
96
+ # method collapse_duplicates return unique controls with applicable findings collapsed into it.
97
+ def collapse_duplicates(controls)
98
+ unique_controls = []
99
+
100
+ controls.map { |x| x['id'] }.uniq.each do |id|
101
+ collapsed_results = controls.select { |x| x['id'].eql?(id) }.map { |x| x['results'] }
102
+ unique_control = controls.find { |x| x['id'].eql?(id) }
103
+ unique_control['results'] = collapsed_results.flatten
104
+ unique_controls << unique_control
105
+ end
106
+ unique_controls
107
+ end
108
108
 
109
109
  def to_hdf
110
110
  controls = []
111
- @project['vulnerabilities'].each do | vulnerability |
111
+ @project['vulnerabilities'].each do |vulnerability|
112
112
  printf("\rProcessing: %s", $spinner.next)
113
113
 
114
114
  item = {}
@@ -125,11 +125,11 @@ module HeimdallTools
125
125
  # Duplicating vulnerability msg field
126
126
  item['desc'] = vulnerability['msg'].to_s
127
127
 
128
- # Nitko does not provide finding severity; hard-coding severity to medium
129
- item['impact'] = impact('medium')
128
+ # Nitko does not provide finding severity; hard-coding severity to medium
129
+ item['impact'] = impact('medium')
130
130
  item['code'] = NA_STRING
131
131
  item['results'] = finding(vulnerability)
132
- item['tags']['nist'] = nist_tag( vulnerability['id'].to_s )
132
+ item['tags']['nist'] = nist_tag(vulnerability['id'].to_s)
133
133
  item['tags']['ösvdb'] = vulnerability['OSVDB']
134
134
 
135
135
  controls << item
@@ -10,12 +10,12 @@ CWE_NIST_MAPPING_FILE = File.join(RESOURCE_DIR, 'cwe-nist-mapping.csv')
10
10
  IMPACT_MAPPING = {
11
11
  high: 0.7,
12
12
  medium: 0.5,
13
- low: 0.3,
13
+ low: 0.3
14
14
  }.freeze
15
15
 
16
16
  SNYK_VERSION_REGEX = 'v(\d+.)(\d+.)(\d+)'.freeze
17
17
 
18
- DEFAULT_NIST_TAG = ["SA-11", "RA-5"].freeze
18
+ DEFAULT_NIST_TAG = %w{SA-11 RA-5}.freeze
19
19
 
20
20
  # Loading spinner sign
21
21
  $spinner = Enumerator.new do |e|
@@ -29,7 +29,7 @@ end
29
29
 
30
30
  module HeimdallTools
31
31
  class SnykMapper
32
- def initialize(synk_json, name=nil, verbose = false)
32
+ def initialize(synk_json, _name = nil, verbose = false)
33
33
  @synk_json = synk_json
34
34
  @verbose = verbose
35
35
 
@@ -38,10 +38,9 @@ module HeimdallTools
38
38
  @projects = JSON.parse(synk_json)
39
39
 
40
40
  # Cover single and multi-project scan use cases.
41
- unless @projects.kind_of?(Array)
42
- @projects = [ @projects ]
41
+ unless @projects.is_a?(Array)
42
+ @projects = [@projects]
43
43
  end
44
-
45
44
  rescue StandardError => e
46
45
  raise "Invalid Snyk JSON file provided Exception: #{e}"
47
46
  end
@@ -52,7 +51,7 @@ module HeimdallTools
52
51
  begin
53
52
  info['policy'] = project['policy']
54
53
  reg = Regexp.new(SNYK_VERSION_REGEX, Regexp::IGNORECASE)
55
- info['version'] = info['policy'].scan(reg).join
54
+ info['version'] = info['policy'].scan(reg).join
56
55
  info['projectName'] = project['projectName']
57
56
  info['summary'] = project['summary']
58
57
 
@@ -65,7 +64,7 @@ module HeimdallTools
65
64
  def finding(vulnerability)
66
65
  finding = {}
67
66
  finding['status'] = 'failed'
68
- finding['code_desc'] = "From : [ #{vulnerability['from'].join(" , ").to_s } ]"
67
+ finding['code_desc'] = "From : [ #{vulnerability['from'].join(' , ')} ]"
69
68
  finding['run_time'] = NA_FLOAT
70
69
 
71
70
  # Snyk results does not profile scan timestamp; using current time to satisfy HDF format
@@ -81,9 +80,9 @@ module HeimdallTools
81
80
 
82
81
  def parse_identifiers(vulnerability, ref)
83
82
  # Extracting id number from reference style CWE-297
84
- vulnerability['identifiers'][ref].map { |e| e.split("#{ref}-")[1] }
85
- rescue
86
- return []
83
+ vulnerability['identifiers'][ref].map { |e| e.split("#{ref}-")[1] }
84
+ rescue StandardError
85
+ []
87
86
  end
88
87
 
89
88
  def impact(severity)
@@ -99,17 +98,17 @@ module HeimdallTools
99
98
  end
100
99
 
101
100
  def desc_tags(data, label)
102
- { "data": data || NA_STRING, "label": label || NA_STRING }
101
+ { data: data || NA_STRING, label: label || NA_STRING }
103
102
  end
104
103
 
105
104
  # Snyk report could have multiple vulnerability entries for multiple findings of same issue type.
106
- # The meta data is identical across entries
105
+ # The meta data is identical across entries
107
106
  # method collapse_duplicates return unique controls with applicable findings collapsed into it.
108
107
  def collapse_duplicates(controls)
109
108
  unique_controls = []
110
109
 
111
110
  controls.map { |x| x['id'] }.uniq.each do |id|
112
- collapsed_results = controls.select { |x| x['id'].eql?(id) }.map {|x| x['results']}
111
+ collapsed_results = controls.select { |x| x['id'].eql?(id) }.map { |x| x['results'] }
113
112
  unique_control = controls.find { |x| x['id'].eql?(id) }
114
113
  unique_control['results'] = collapsed_results.flatten
115
114
  unique_controls << unique_control
@@ -117,12 +116,11 @@ module HeimdallTools
117
116
  unique_controls
118
117
  end
119
118
 
120
-
121
119
  def to_hdf
122
120
  project_results = {}
123
- @projects.each do | project |
121
+ @projects.each do |project|
124
122
  controls = []
125
- project['vulnerabilities'].each do | vulnerability |
123
+ project['vulnerabilities'].each do |vulnerability|
126
124
  printf("\rProcessing: %s", $spinner.next)
127
125
 
128
126
  item = {}
@@ -135,13 +133,13 @@ module HeimdallTools
135
133
  item['title'] = vulnerability['title'].to_s
136
134
  item['id'] = vulnerability['id'].to_s
137
135
  item['desc'] = vulnerability['description'].to_s
138
- item['impact'] = impact(vulnerability['severity'])
136
+ item['impact'] = impact(vulnerability['severity'])
139
137
  item['code'] = ''
140
138
  item['results'] = finding(vulnerability)
141
- item['tags']['nist'] = nist_tag( parse_identifiers( vulnerability, 'CWE') )
142
- item['tags']['cweid'] = parse_identifiers( vulnerability, 'CWE')
143
- item['tags']['cveid'] = parse_identifiers( vulnerability, 'CVE')
144
- item['tags']['ghsaid'] = parse_identifiers( vulnerability, 'GHSA')
139
+ item['tags']['nist'] = nist_tag(parse_identifiers(vulnerability, 'CWE'))
140
+ item['tags']['cweid'] = parse_identifiers(vulnerability, 'CWE')
141
+ item['tags']['cveid'] = parse_identifiers(vulnerability, 'CVE')
142
+ item['tags']['ghsaid'] = parse_identifiers(vulnerability, 'GHSA')
145
143
 
146
144
  controls << item
147
145
  end