heimdall_tools 1.3.40 → 1.3.41

Sign up to get free protection for your applications and to get access to all the features.
@@ -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