heimdall_tools 1.3.37 → 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.
- checksums.yaml +4 -4
- data/README.md +18 -0
- data/lib/heimdall_tools.rb +1 -0
- data/lib/heimdall_tools/aws_config_mapper.rb +26 -26
- data/lib/heimdall_tools/burpsuite_mapper.rb +8 -12
- data/lib/heimdall_tools/cli.rb +19 -8
- data/lib/heimdall_tools/command.rb +0 -2
- data/lib/heimdall_tools/dbprotect_mapper.rb +9 -18
- data/lib/heimdall_tools/fortify_mapper.rb +1 -2
- data/lib/heimdall_tools/hdf.rb +4 -5
- data/lib/heimdall_tools/help/netsparker_mapper.md +7 -0
- data/lib/heimdall_tools/jfrog_xray_mapper.rb +34 -27
- data/lib/heimdall_tools/nessus_mapper.rb +39 -46
- data/lib/heimdall_tools/netsparker_mapper.rb +164 -0
- data/lib/heimdall_tools/nikto_mapper.rb +28 -28
- data/lib/heimdall_tools/snyk_mapper.rb +21 -23
- data/lib/heimdall_tools/sonarqube_mapper.rb +23 -21
- data/lib/heimdall_tools/zap_mapper.rb +4 -5
- data/lib/utilities/xml_to_hash.rb +6 -6
- metadata +40 -24
@@ -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 =
|
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,
|
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
|
-
|
40
|
-
|
41
|
-
|
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,14 +64,14 @@ module HeimdallTools
|
|
64
64
|
def finding(vulnerability)
|
65
65
|
finding = {}
|
66
66
|
finding['status'] = 'failed'
|
67
|
-
finding['code_desc'] = "URL : #{vulnerability['url']
|
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]
|
71
71
|
end
|
72
72
|
|
73
73
|
def nist_tag(niktoid)
|
74
|
-
entries = @nikto_nist_mapping.select { |x| niktoid.eql?(x[:niktoid].to_s) }
|
74
|
+
entries = @nikto_nist_mapping.select { |x| niktoid.eql?(x[:niktoid].to_s) && !x[:nistid].nil? }
|
75
75
|
tags = entries.map { |x| x[:nistid] }
|
76
76
|
tags.empty? ? DEFAULT_NIST_TAG : tags.flatten.uniq
|
77
77
|
end
|
@@ -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
|
-
{
|
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 |
|
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(
|
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 =
|
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,
|
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.
|
42
|
-
@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(
|
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
|
@@ -74,16 +73,16 @@ module HeimdallTools
|
|
74
73
|
end
|
75
74
|
|
76
75
|
def nist_tag(cweid)
|
77
|
-
entries = @cwe_nist_mapping.select { |x| cweid.include?
|
76
|
+
entries = @cwe_nist_mapping.select { |x| cweid.include?(x[:cweid].to_s) && !x[:nistid].nil? }
|
78
77
|
tags = entries.map { |x| x[:nistid] }
|
79
78
|
tags.empty? ? DEFAULT_NIST_TAG : tags.flatten.uniq
|
80
79
|
end
|
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
|
-
|
86
|
-
|
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
|
-
{
|
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 |
|
121
|
+
@projects.each do |project|
|
124
122
|
controls = []
|
125
|
-
project['vulnerabilities'].each do |
|
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(
|
142
|
-
item['tags']['cweid'] = parse_identifiers(
|
143
|
-
item['tags']['cveid'] = parse_identifiers(
|
144
|
-
item['tags']['ghsaid'] = parse_identifiers(
|
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
|
@@ -5,7 +5,7 @@ require 'heimdall_tools/hdf'
|
|
5
5
|
|
6
6
|
RESOURCE_DIR = Pathname.new(__FILE__).join('../../data')
|
7
7
|
|
8
|
-
DEFAULT_NIST_TAG =
|
8
|
+
DEFAULT_NIST_TAG = %w{SA-11 RA-5}.freeze
|
9
9
|
|
10
10
|
MAPPING_FILES = {
|
11
11
|
cwe: File.join(RESOURCE_DIR, 'cwe-nist-mapping.csv'),
|
@@ -33,16 +33,18 @@ class SonarQubeApi
|
|
33
33
|
|
34
34
|
PAGE_SIZE = 100
|
35
35
|
|
36
|
-
def initialize(api_url, auth=nil)
|
36
|
+
def initialize(api_url, auth = nil)
|
37
37
|
@api_url = api_url
|
38
38
|
@auth = auth
|
39
39
|
end
|
40
40
|
|
41
|
-
def query_api(endpoint, params={})
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
41
|
+
def query_api(endpoint, params = {})
|
42
|
+
unless @auth.nil?
|
43
|
+
creds = {
|
44
|
+
username: @auth.split(':')[0],
|
45
|
+
password: @auth.split(':')[1]
|
46
|
+
}
|
47
|
+
end
|
46
48
|
|
47
49
|
response = HTTParty.get(@api_url + endpoint, { query: params, basic_auth: creds })
|
48
50
|
check_response response
|
@@ -109,9 +111,9 @@ end
|
|
109
111
|
module HeimdallTools
|
110
112
|
class SonarQubeMapper
|
111
113
|
# Fetches the necessary data from the API and builds report
|
112
|
-
def initialize(project_name, sonarqube_url, auth=nil)
|
114
|
+
def initialize(project_name, sonarqube_url, auth = nil)
|
113
115
|
@project_name = project_name
|
114
|
-
@api = SonarQubeApi.new(sonarqube_url,auth)
|
116
|
+
@api = SonarQubeApi.new(sonarqube_url, auth)
|
115
117
|
|
116
118
|
@mappings = load_nist_mappings
|
117
119
|
@findings = @api.query_issues(@project_name).map { |x| Finding.new(x, @api) }
|
@@ -132,16 +134,16 @@ module HeimdallTools
|
|
132
134
|
headers: true,
|
133
135
|
header_converters: :symbol,
|
134
136
|
converters: :all })
|
135
|
-
mappings[mapping_type] =
|
136
|
-
[row[
|
137
|
-
}
|
137
|
+
mappings[mapping_type] = csv_data.reject { |row| row[:nistid].nil? }.map { |row|
|
138
|
+
[row["#{mapping_type.to_s.downcase}id".to_sym].to_s, [row[:nistid], "Rev_#{row[:rev]}"]]
|
139
|
+
}.to_h
|
138
140
|
end
|
139
141
|
mappings
|
140
142
|
end
|
141
143
|
|
142
144
|
# Returns a report in HDF format
|
143
145
|
def to_hdf
|
144
|
-
results = HeimdallDataFormat.new(profile_name:
|
146
|
+
results = HeimdallDataFormat.new(profile_name: 'SonarQube Scan',
|
145
147
|
version: @api.query_version,
|
146
148
|
title: "SonarQube Scan of Project: #{@project_name}",
|
147
149
|
summary: "SonarQube Scan of Project: #{@project_name}",
|
@@ -156,7 +158,7 @@ class Control
|
|
156
158
|
# OWASP is stated specifically, ex owasp-a1
|
157
159
|
#
|
158
160
|
# SonarQube is inconsistent with tags (ex some cwe rules don't have cwe number in desc,) as noted below
|
159
|
-
TAG_DATA = {} # NOTE: We count on Ruby to preserve order for TAG_DATA
|
161
|
+
TAG_DATA = {}.freeze # NOTE: We count on Ruby to preserve order for TAG_DATA
|
160
162
|
TAG_DATA[:cwe] = {
|
161
163
|
# Some rules with cwe tag don't have cwe number in description!
|
162
164
|
# Currently only squid:S2658, but it has OWASP tag so we can use that.
|
@@ -206,8 +208,8 @@ class Control
|
|
206
208
|
reg = Regexp.new(tag_data[:regex], Regexp::IGNORECASE)
|
207
209
|
parsed_tags += @data['htmlDesc'].scan(reg).map(&:first)
|
208
210
|
|
209
|
-
if parsed_tags.empty? and not KNOWN_BAD_RULES.include? @key
|
210
|
-
puts "Error: Rule #{@key}: No regex matches for #{tag_type} tag."
|
211
|
+
if parsed_tags.empty? and not KNOWN_BAD_RULES.include? @key && parsed_tags.empty?
|
212
|
+
puts "Error: Rule #{@key}: No regex matches for #{tag_type} tag."
|
211
213
|
end
|
212
214
|
else
|
213
215
|
# If the tag type doesn't have a regex, it is specific enough to be mapped directly
|
@@ -239,11 +241,11 @@ class Control
|
|
239
241
|
return [@mappings[tag_type][parsed_tag]].flatten.uniq
|
240
242
|
end
|
241
243
|
|
242
|
-
DEFAULT_NIST_TAG # Entries with unmapped NIST tags
|
244
|
+
DEFAULT_NIST_TAG # Entries with unmapped NIST tags fall back to defaults
|
243
245
|
end
|
244
246
|
|
245
247
|
def hdf
|
246
|
-
#
|
248
|
+
# NOTE: Structure is based on fortify -> HDF converter output
|
247
249
|
{
|
248
250
|
title: @data['name'],
|
249
251
|
desc: @data['htmlDesc'],
|
@@ -256,7 +258,7 @@ class Control
|
|
256
258
|
id: @key,
|
257
259
|
descriptions: NA_ARRAY,
|
258
260
|
refs: NA_ARRAY,
|
259
|
-
source_location: NA_HASH
|
261
|
+
source_location: NA_HASH
|
260
262
|
}
|
261
263
|
end
|
262
264
|
end
|
@@ -284,10 +286,10 @@ class Finding
|
|
284
286
|
|
285
287
|
snip_html = "StartLine: #{snip_start}, EndLine: #{snip_end}<br>Code:<pre>#{snip}</pre>"
|
286
288
|
{
|
287
|
-
|
289
|
+
status: 'failed',
|
288
290
|
code_desc: "Path:#{component}:#{vuln_start}:#{vuln_end} #{snip_html}",
|
289
291
|
run_time: NA_FLOAT,
|
290
|
-
start_time: Time.now.strftime(
|
292
|
+
start_time: Time.now.strftime('%a,%d %b %Y %X')
|
291
293
|
}
|
292
294
|
end
|
293
295
|
end
|
@@ -3,11 +3,10 @@ require 'nokogiri'
|
|
3
3
|
require 'csv'
|
4
4
|
require 'heimdall_tools/hdf'
|
5
5
|
|
6
|
-
|
7
6
|
RESOURCE_DIR = Pathname.new(__FILE__).join('../../data')
|
8
7
|
|
9
8
|
CWE_NIST_MAPPING_FILE = File.join(RESOURCE_DIR, 'cwe-nist-mapping.csv')
|
10
|
-
DEFAULT_NIST_TAG =
|
9
|
+
DEFAULT_NIST_TAG = %w{SA-11 RA-5}.freeze
|
11
10
|
|
12
11
|
# rubocop:disable Metrics/AbcSize
|
13
12
|
|
@@ -58,14 +57,14 @@ module HeimdallTools
|
|
58
57
|
|
59
58
|
def format_code_desc(code_desc)
|
60
59
|
desc = ''
|
61
|
-
code_desc.
|
60
|
+
code_desc.each_key do |key|
|
62
61
|
desc += "#{key.capitalize}: #{code_desc[key]}\n"
|
63
62
|
end
|
64
63
|
desc
|
65
64
|
end
|
66
65
|
|
67
66
|
def nist_tag(cweid)
|
68
|
-
entries = @cwe_nist_mapping.select { |x| x[:cweid].to_s.eql?(cweid.to_s) }
|
67
|
+
entries = @cwe_nist_mapping.select { |x| x[:cweid].to_s.eql?(cweid.to_s) && !x[:nistid].nil? }
|
69
68
|
tags = entries.map { |x| [x[:nistid], "Rev_#{x[:rev]}"] }
|
70
69
|
tags.empty? ? DEFAULT_NIST_TAG : tags.flatten.uniq
|
71
70
|
end
|
@@ -98,7 +97,7 @@ module HeimdallTools
|
|
98
97
|
dup_ids.each do |dup_id|
|
99
98
|
index = 1
|
100
99
|
controls.select { |x| x['id'].eql?(dup_id) }.each do |control|
|
101
|
-
control['id'] = control['id']
|
100
|
+
control['id'] = "#{control['id']}.#{index}"
|
102
101
|
index += 1
|
103
102
|
end
|
104
103
|
end
|
@@ -6,11 +6,13 @@ def xml_node_to_hash(node)
|
|
6
6
|
result_hash = {}
|
7
7
|
if node.attributes != {}
|
8
8
|
attributes = {}
|
9
|
-
node.attributes.
|
9
|
+
node.attributes.each_key do |key|
|
10
10
|
attributes[node.attributes[key].name] = node.attributes[key].value
|
11
11
|
end
|
12
12
|
end
|
13
|
-
if
|
13
|
+
if node.children.empty?
|
14
|
+
attributes
|
15
|
+
else
|
14
16
|
node.children.each do |child|
|
15
17
|
result = xml_node_to_hash(child)
|
16
18
|
|
@@ -36,9 +38,7 @@ def xml_node_to_hash(node)
|
|
36
38
|
# if there is a collision then node content supersets attributes
|
37
39
|
result_hash = attributes.merge(result_hash)
|
38
40
|
end
|
39
|
-
|
40
|
-
else
|
41
|
-
return attributes
|
41
|
+
result_hash
|
42
42
|
end
|
43
43
|
else
|
44
44
|
node.content.to_s
|
@@ -47,7 +47,7 @@ end
|
|
47
47
|
|
48
48
|
def xml_to_hash(xml)
|
49
49
|
begin
|
50
|
-
data = Nokogiri::XML(xml
|
50
|
+
data = Nokogiri::XML(xml, &:strict)
|
51
51
|
rescue Nokogiri::XML::SyntaxError => e
|
52
52
|
puts "XML Parsing caught exception: #{e}"
|
53
53
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: heimdall_tools
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.41
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Robert Thew
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2021-03-
|
13
|
+
date: 2021-03-29 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: aws-sdk-configservice
|
@@ -27,75 +27,75 @@ dependencies:
|
|
27
27
|
- !ruby/object:Gem::Version
|
28
28
|
version: '1'
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
|
-
name:
|
30
|
+
name: csv
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
32
32
|
requirements:
|
33
33
|
- - "~>"
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: 1
|
35
|
+
version: '3.1'
|
36
36
|
type: :runtime
|
37
37
|
prerelease: false
|
38
38
|
version_requirements: !ruby/object:Gem::Requirement
|
39
39
|
requirements:
|
40
40
|
- - "~>"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: 1
|
42
|
+
version: '3.1'
|
43
43
|
- !ruby/object:Gem::Dependency
|
44
|
-
name:
|
44
|
+
name: git-lite-version-bump
|
45
45
|
requirement: !ruby/object:Gem::Requirement
|
46
46
|
requirements:
|
47
|
-
- - "
|
47
|
+
- - ">="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version:
|
49
|
+
version: 0.17.2
|
50
50
|
type: :runtime
|
51
51
|
prerelease: false
|
52
52
|
version_requirements: !ruby/object:Gem::Requirement
|
53
53
|
requirements:
|
54
|
-
- - "
|
54
|
+
- - ">="
|
55
55
|
- !ruby/object:Gem::Version
|
56
|
-
version:
|
56
|
+
version: 0.17.2
|
57
57
|
- !ruby/object:Gem::Dependency
|
58
|
-
name:
|
58
|
+
name: httparty
|
59
59
|
requirement: !ruby/object:Gem::Requirement
|
60
60
|
requirements:
|
61
61
|
- - "~>"
|
62
62
|
- !ruby/object:Gem::Version
|
63
|
-
version:
|
63
|
+
version: 0.18.0
|
64
64
|
type: :runtime
|
65
65
|
prerelease: false
|
66
66
|
version_requirements: !ruby/object:Gem::Requirement
|
67
67
|
requirements:
|
68
68
|
- - "~>"
|
69
69
|
- !ruby/object:Gem::Version
|
70
|
-
version:
|
70
|
+
version: 0.18.0
|
71
71
|
- !ruby/object:Gem::Dependency
|
72
|
-
name:
|
72
|
+
name: json
|
73
73
|
requirement: !ruby/object:Gem::Requirement
|
74
74
|
requirements:
|
75
75
|
- - "~>"
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version: '3
|
77
|
+
version: '2.3'
|
78
78
|
type: :runtime
|
79
79
|
prerelease: false
|
80
80
|
version_requirements: !ruby/object:Gem::Requirement
|
81
81
|
requirements:
|
82
82
|
- - "~>"
|
83
83
|
- !ruby/object:Gem::Version
|
84
|
-
version: '3
|
84
|
+
version: '2.3'
|
85
85
|
- !ruby/object:Gem::Dependency
|
86
|
-
name:
|
86
|
+
name: nokogiri
|
87
87
|
requirement: !ruby/object:Gem::Requirement
|
88
88
|
requirements:
|
89
89
|
- - "~>"
|
90
90
|
- !ruby/object:Gem::Version
|
91
|
-
version:
|
91
|
+
version: 1.10.9
|
92
92
|
type: :runtime
|
93
93
|
prerelease: false
|
94
94
|
version_requirements: !ruby/object:Gem::Requirement
|
95
95
|
requirements:
|
96
96
|
- - "~>"
|
97
97
|
- !ruby/object:Gem::Version
|
98
|
-
version:
|
98
|
+
version: 1.10.9
|
99
99
|
- !ruby/object:Gem::Dependency
|
100
100
|
name: openssl
|
101
101
|
requirement: !ruby/object:Gem::Requirement
|
@@ -111,19 +111,19 @@ dependencies:
|
|
111
111
|
- !ruby/object:Gem::Version
|
112
112
|
version: '2.1'
|
113
113
|
- !ruby/object:Gem::Dependency
|
114
|
-
name:
|
114
|
+
name: thor
|
115
115
|
requirement: !ruby/object:Gem::Requirement
|
116
116
|
requirements:
|
117
|
-
- - "
|
117
|
+
- - "~>"
|
118
118
|
- !ruby/object:Gem::Version
|
119
|
-
version: 0.
|
119
|
+
version: '0.19'
|
120
120
|
type: :runtime
|
121
121
|
prerelease: false
|
122
122
|
version_requirements: !ruby/object:Gem::Requirement
|
123
123
|
requirements:
|
124
|
-
- - "
|
124
|
+
- - "~>"
|
125
125
|
- !ruby/object:Gem::Version
|
126
|
-
version: 0.
|
126
|
+
version: '0.19'
|
127
127
|
- !ruby/object:Gem::Dependency
|
128
128
|
name: bundler
|
129
129
|
requirement: !ruby/object:Gem::Requirement
|
@@ -180,6 +180,20 @@ dependencies:
|
|
180
180
|
- - ">="
|
181
181
|
- !ruby/object:Gem::Version
|
182
182
|
version: '0'
|
183
|
+
- !ruby/object:Gem::Dependency
|
184
|
+
name: rubocop
|
185
|
+
requirement: !ruby/object:Gem::Requirement
|
186
|
+
requirements:
|
187
|
+
- - "~>"
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '1.11'
|
190
|
+
type: :development
|
191
|
+
prerelease: false
|
192
|
+
version_requirements: !ruby/object:Gem::Requirement
|
193
|
+
requirements:
|
194
|
+
- - "~>"
|
195
|
+
- !ruby/object:Gem::Version
|
196
|
+
version: '1.11'
|
183
197
|
description: Converter utils that can be included as a gem or used from the command
|
184
198
|
line
|
185
199
|
email:
|
@@ -215,12 +229,14 @@ files:
|
|
215
229
|
- lib/heimdall_tools/help/fortify_mapper.md
|
216
230
|
- lib/heimdall_tools/help/jfrog_xray_mapper.md
|
217
231
|
- lib/heimdall_tools/help/nessus_mapper.md
|
232
|
+
- lib/heimdall_tools/help/netsparker_mapper.md
|
218
233
|
- lib/heimdall_tools/help/nikto_mapper.md
|
219
234
|
- lib/heimdall_tools/help/snyk_mapper.md
|
220
235
|
- lib/heimdall_tools/help/sonarqube_mapper.md
|
221
236
|
- lib/heimdall_tools/help/zap_mapper.md
|
222
237
|
- lib/heimdall_tools/jfrog_xray_mapper.rb
|
223
238
|
- lib/heimdall_tools/nessus_mapper.rb
|
239
|
+
- lib/heimdall_tools/netsparker_mapper.rb
|
224
240
|
- lib/heimdall_tools/nikto_mapper.rb
|
225
241
|
- lib/heimdall_tools/snyk_mapper.rb
|
226
242
|
- lib/heimdall_tools/sonarqube_mapper.rb
|