heimdall_tools 1.2.0 → 1.3.20

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
- SHA1:
3
- metadata.gz: 16faf735e553864867f8e551ea92b96621eeb415
4
- data.tar.gz: 2baa94079e6561d38c5c8511e39691a15d360619
2
+ SHA256:
3
+ metadata.gz: 83950f4cf536e2df5b1fc18b6a5a910623c80ac1a064be6b7b1281b6dec61b74
4
+ data.tar.gz: cca52d5d8bf483a372029578277039303017bd02b73273d01e106b41e772fbfe
5
5
  SHA512:
6
- metadata.gz: ba635075511c4299786f38a763625197da934bf3aa72d992c9da464bdfc8f992f7734d26907aaf67aa71c40c9f37f22232e32173e44e7302d06254a788c7a618
7
- data.tar.gz: 7dbe62ad30fef7ed3a6eef4570ad5e4500345947013b2d152842c024fbffb4a5bf640f431861443ad49d1d5d99c429db7d39d8149c05c97a2b0e3b69480c2563
6
+ metadata.gz: bed11c34a71d7c8e893e1a4402abdb95b5ed5d6b959d7ebe117e0b3ef08cef650c2903da6074752202e7b603b3511eb3084dcf92729f603e6e97fa26a1b12556
7
+ data.tar.gz: 964c873a24db4ec4620435f3e3a08f48f1aaa1e54b04b1eca93dbbd3a9a49c6c7fe15a5d45c0e2d06d969daac99c43ad906cb023c232be12dabfdeae318308ee
data/CHANGELOG.md CHANGED
@@ -1,7 +1,154 @@
1
- # Change Log
1
+ # Changelog
2
2
 
3
- All notable changes to this project will be documented in this file.
4
- This project *tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
3
+ ## [Unreleased](https://github.com/mitre/heimdall_tools/tree/HEAD)
5
4
 
6
- ## [1.0.1]
7
- - Initial internal release.
5
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.19...HEAD)
6
+
7
+ **Fixed bugs:**
8
+
9
+ - Unable to Convert Fortify 19.2.0 FVDL file to HDF [\#25](https://github.com/mitre/heimdall_tools/issues/25)
10
+
11
+ ## [v1.3.19](https://github.com/mitre/heimdall_tools/tree/v1.3.19) (2020-03-30)
12
+
13
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.18...v1.3.19)
14
+
15
+ **Merged pull requests:**
16
+
17
+ - Remove all gems from Gemfile and declare them properly in the gemspec [\#33](https://github.com/mitre/heimdall_tools/pull/33) ([rbclark](https://github.com/rbclark))
18
+
19
+ ## [v1.3.18](https://github.com/mitre/heimdall_tools/tree/v1.3.18) (2020-03-28)
20
+
21
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.17...v1.3.18)
22
+
23
+ ## [v1.3.17](https://github.com/mitre/heimdall_tools/tree/v1.3.17) (2020-03-26)
24
+
25
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.16...v1.3.17)
26
+
27
+ **Closed issues:**
28
+
29
+ - Request New converters [\#23](https://github.com/mitre/heimdall_tools/issues/23)
30
+
31
+ ## [v1.3.16](https://github.com/mitre/heimdall_tools/tree/v1.3.16) (2020-03-25)
32
+
33
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.15...v1.3.16)
34
+
35
+ ## [v1.3.15](https://github.com/mitre/heimdall_tools/tree/v1.3.15) (2020-03-25)
36
+
37
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.14...v1.3.15)
38
+
39
+ ## [v1.3.14](https://github.com/mitre/heimdall_tools/tree/v1.3.14) (2020-03-24)
40
+
41
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.13...v1.3.14)
42
+
43
+ ## [v1.3.13](https://github.com/mitre/heimdall_tools/tree/v1.3.13) (2020-03-24)
44
+
45
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.12...v1.3.13)
46
+
47
+ ## [v1.3.12](https://github.com/mitre/heimdall_tools/tree/v1.3.12) (2020-03-24)
48
+
49
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.11...v1.3.12)
50
+
51
+ ## [v1.3.11](https://github.com/mitre/heimdall_tools/tree/v1.3.11) (2020-03-24)
52
+
53
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.10...v1.3.11)
54
+
55
+ ## [v1.3.10](https://github.com/mitre/heimdall_tools/tree/v1.3.10) (2020-03-24)
56
+
57
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.9...v1.3.10)
58
+
59
+ ## [v1.3.9](https://github.com/mitre/heimdall_tools/tree/v1.3.9) (2020-03-23)
60
+
61
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.8...v1.3.9)
62
+
63
+ **Closed issues:**
64
+
65
+ - Update XML parser [\#26](https://github.com/mitre/heimdall_tools/issues/26)
66
+
67
+ **Merged pull requests:**
68
+
69
+ - Update XML parser [\#27](https://github.com/mitre/heimdall_tools/pull/27) ([rx294](https://github.com/rx294))
70
+
71
+ ## [v1.3.8](https://github.com/mitre/heimdall_tools/tree/v1.3.8) (2020-03-09)
72
+
73
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.7...v1.3.8)
74
+
75
+ **Closed issues:**
76
+
77
+ - \[BUG\] | sonarqube\_mapper is not handling NIST mapping correctly [\#21](https://github.com/mitre/heimdall_tools/issues/21)
78
+
79
+ **Merged pull requests:**
80
+
81
+ - Fixes \#21 \[BUG\] | sonarqube\_mapper is not handling NIST mapping correctly [\#22](https://github.com/mitre/heimdall_tools/pull/22) ([rx294](https://github.com/rx294))
82
+
83
+ ## [v1.3.7](https://github.com/mitre/heimdall_tools/tree/v1.3.7) (2020-03-06)
84
+
85
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.6...v1.3.7)
86
+
87
+ ## [v1.3.6](https://github.com/mitre/heimdall_tools/tree/v1.3.6) (2020-03-05)
88
+
89
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.5...v1.3.6)
90
+
91
+ ## [v1.3.5](https://github.com/mitre/heimdall_tools/tree/v1.3.5) (2020-03-05)
92
+
93
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.4...v1.3.5)
94
+
95
+ ## [v1.3.4](https://github.com/mitre/heimdall_tools/tree/v1.3.4) (2020-03-04)
96
+
97
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.3...v1.3.4)
98
+
99
+ **Closed issues:**
100
+
101
+ - Support Authenticated Sonarqube API for sonarqube\_mapper [\#18](https://github.com/mitre/heimdall_tools/issues/18)
102
+
103
+ ## [v1.3.3](https://github.com/mitre/heimdall_tools/tree/v1.3.3) (2020-03-04)
104
+
105
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.2...v1.3.3)
106
+
107
+ **Merged pull requests:**
108
+
109
+ - Sonarqube authentication option [\#20](https://github.com/mitre/heimdall_tools/pull/20) ([rx294](https://github.com/rx294))
110
+
111
+ ## [v1.3.2](https://github.com/mitre/heimdall_tools/tree/v1.3.2) (2019-12-27)
112
+
113
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.1...v1.3.2)
114
+
115
+ **Merged pull requests:**
116
+
117
+ - Adding dockerfile for heimdall tools [\#15](https://github.com/mitre/heimdall_tools/pull/15) ([rx294](https://github.com/rx294))
118
+
119
+ ## [v1.3.1](https://github.com/mitre/heimdall_tools/tree/v1.3.1) (2019-12-27)
120
+
121
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/v1.3.0...v1.3.1)
122
+
123
+ **Closed issues:**
124
+
125
+ - Update HDF format generate jsons in Inspec results style [\#10](https://github.com/mitre/heimdall_tools/issues/10)
126
+
127
+ **Merged pull requests:**
128
+
129
+ - Updating required nori gem version [\#16](https://github.com/mitre/heimdall_tools/pull/16) ([rx294](https://github.com/rx294))
130
+ - Populate shasum and runtime field [\#14](https://github.com/mitre/heimdall_tools/pull/14) ([rx294](https://github.com/rx294))
131
+ - Updates as per feedback [\#13](https://github.com/mitre/heimdall_tools/pull/13) ([rx294](https://github.com/rx294))
132
+ - updating samples [\#12](https://github.com/mitre/heimdall_tools/pull/12) ([rx294](https://github.com/rx294))
133
+ - Change to results view on heimdall [\#11](https://github.com/mitre/heimdall_tools/pull/11) ([rx294](https://github.com/rx294))
134
+
135
+ ## [v1.3.0](https://github.com/mitre/heimdall_tools/tree/v1.3.0) (2019-09-24)
136
+
137
+ [Full Changelog](https://github.com/mitre/heimdall_tools/compare/c9c08305796eaf12d7abb2535c285a4acd2f5a91...v1.3.0)
138
+
139
+ **Closed issues:**
140
+
141
+ - README needs authors [\#9](https://github.com/mitre/heimdall_tools/issues/9)
142
+ - Get NIST rev version from CSV [\#4](https://github.com/mitre/heimdall_tools/issues/4)
143
+ - Output in evaluation format, not profile [\#2](https://github.com/mitre/heimdall_tools/issues/2)
144
+
145
+ **Merged pull requests:**
146
+
147
+ - Fixes to PR \#6 [\#8](https://github.com/mitre/heimdall_tools/pull/8) ([rx294](https://github.com/rx294))
148
+ - Update README fortify-fvdl flag to fvdl as in usage [\#7](https://github.com/mitre/heimdall_tools/pull/7) ([mirskiy](https://github.com/mirskiy))
149
+ - Add SonarQube Mapper and OWASP NIST mappings [\#6](https://github.com/mitre/heimdall_tools/pull/6) ([mirskiy](https://github.com/mirskiy))
150
+ - OWASP ZAP Mapper PR [\#3](https://github.com/mitre/heimdall_tools/pull/3) ([rx294](https://github.com/rx294))
151
+
152
+
153
+
154
+ \* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)*
data/README.md CHANGED
@@ -1,6 +1,8 @@
1
- # WIP - ALPHA
1
+ # Heimdall Tools
2
2
 
3
- # HeimdallTools
3
+ ![Overall Status](https://github.com/mitre/heimdall_tools/workflows/heimdall_tools/badge.svg)
4
+
5
+ ![Heimdall Tools Build](https://github.com/mitre/heimdall_tools/workflows/Build%20and%20run%20heimdall_tools/badge.svg)
4
6
 
5
7
  HeimdallTools supplies several methods to convert output from various tools to "Heimdall Data Format"(HDF) format to be viewable in Heimdall. The converters in version 1.1.1 are from:
6
8
 
@@ -41,12 +43,17 @@ sonarqube_mapper pulls SonarQube results, for the specified project, from the AP
41
43
  USAGE: heimdall_tools sonarqube_mapper [OPTIONS] -n <project-name> -u <api-url> -o <scan-results.json>
42
44
 
43
45
  FLAGS:
44
- -n --name <project-name> : name of the project in SonarQube, aka Project Key
46
+ -n --name <project-key> : Project Key of the project in SonarQube
45
47
  -u --api_url <api-url> : url of the SonarQube Server API. Typically ends with /api.
48
+ --auth <credentials> : username:password or token [optional].
46
49
  -o --output <scan-results> : path to output scan-results json.
47
50
  -V --verbose : verbose run [optional].
48
51
 
49
- example: heimdall_tools sonarqube_mapper -n sonar_project -u http://sonar:9000/api -o scan_results.json
52
+ example:
53
+
54
+ heimdall_tools sonarqube_mapper -n sonar_project_key -u http://sonar:9000/api -o scan_results.json
55
+
56
+ heimdall_tools sonarqube_mapper -n sonar_project_key -u http://sonar:9000/api --auth admin:admin -o scan_results.json
50
57
  ```
51
58
 
52
59
  ## fortify_mapper
@@ -90,6 +97,42 @@ USAGE: heimdall_tools version
90
97
 
91
98
  # Development
92
99
 
100
+ ## Submitting a PR
101
+
102
+ ### A complete PR should include 7 core elements:
103
+
104
+ - A signed PR ( aka `git commit -a -s` )
105
+ - Code for the new functionality
106
+ - Updates to the CLI
107
+ - New unit tests for the functionality
108
+ - Updates to the docs and examples in `README.md` and `./docs/*`
109
+ - (if needed) Example / Template files ( `metadata.yml`,`example.yml`, etc )
110
+ - Scripts / Scaffolding code for the Example / Template files ( `generate_map` is an example )
111
+ - Example Output of the new functionality if it produces an artifact
112
+
113
+ ### Overview of our PR process
114
+
115
+ 1. open an issue on the main inspec_tools website noting the issues your PR will address
116
+ 2. fork the repo
117
+ 3. checkout your repo
118
+ 4. cd to the repo
119
+ 5. git co -b `<your_branch>`
120
+ 6. bundle install
121
+ 7. `hack as you will`
122
+ 8. test via rake
123
+ 9. ensure unit tests still function and add unit tests for your new feature
124
+ 10. add new docs to the `README.md` and to `./docs/examples`
125
+ 11. update the CLI as needed and add in `usage` example
126
+ 12. (if needed) create and document any example or templates
127
+ 13. (if needed) create any supporing scripts
128
+ 14. (opt) gem build inspec_tools.gemspec
129
+ 15. (opt) gem install inspec_tools
130
+ 16. (opt) test via the installed gem
131
+ 17. git commit -a -s `<your_branch>`
132
+ 18. Open a PRs aginst the MITRE inspec_tools repo
133
+
134
+ # Testing
135
+
93
136
  This gem was developed using the [CLI Template](https://github.com/tongueroo/cli-template), a generator tool that builds a starter CLI project.
94
137
 
95
138
  There are a set of unit tests. Run `rake test` to run the tests.
data/exe/heimdall_tools CHANGED
@@ -1,4 +1,4 @@
1
- #!/usr/bin/env ruby
1
+ #!/usr/bin/env -Sruby -EUTF-8
2
2
 
3
3
  # Trap ^C
4
4
  Signal.trap('INT') {
@@ -27,10 +27,11 @@ module HeimdallTools
27
27
  long_desc Help.text(:sonarqube_mapper)
28
28
  option :name, required: true, aliases: '-n'
29
29
  option :api_url, required: true, aliases: '-u'
30
+ option :auth, type: :string, required: false
30
31
  option :output, required: true, aliases: '-o'
31
32
  option :verbose, type: :boolean, aliases: '-V'
32
33
  def sonarqube_mapper
33
- hdf = HeimdallTools::SonarQubeMapper.new(options[:name], options[:api_url]).to_hdf
34
+ hdf = HeimdallTools::SonarQubeMapper.new(options[:name], options[:api_url], options[:auth]).to_hdf
34
35
  File.write(options[:output], hdf)
35
36
  end
36
37
 
@@ -1,6 +1,6 @@
1
1
  require 'json'
2
- require 'nokogiri'
3
- require 'nori'
2
+ require 'heimdall_tools/hdf'
3
+ require 'utilities/xml_to_hash'
4
4
 
5
5
  NIST_REFERENCE_NAME = 'Standards Mapping - NIST Special Publication 800-53 Revision 4'.freeze
6
6
 
@@ -11,21 +11,26 @@ module HeimdallTools
11
11
  @verbose = verbose
12
12
 
13
13
  begin
14
- data = Nori.new(empty_tag_value: true).parse(fvdl)
14
+ data = xml_to_hash(fvdl)
15
15
  @timestamp = data['FVDL']['CreatedTS']
16
16
  @vulns = data['FVDL']['Vulnerabilities']['Vulnerability']
17
17
  @snippets = data['FVDL']['Snippets']['Snippet']
18
18
  @rules = data['FVDL']['Description']
19
+ @uuid = data['FVDL']['UUID']
20
+ @fortify_version = data['FVDL']['EngineData']['EngineVersion']
21
+
19
22
  rescue StandardError => e
20
23
  raise "Invalid Fortify FVDL file provided Exception: #{e}"
21
24
  end
22
25
  end
23
26
 
24
27
  def process_entry(entry)
25
- snippetid = entry['Node']['SourceLocation']['@snippet']
28
+ snippetid = entry['Node']['SourceLocation']['snippet']
26
29
  finding = {}
27
30
  finding['status'] = 'failed'
28
31
  finding['code_desc'] = snippet(snippetid)
32
+ finding['run_time'] = NA_FLOAT
33
+ finding['start_time'] = [@timestamp['date'], @timestamp['time']].join(' ')
29
34
  finding
30
35
  end
31
36
 
@@ -48,11 +53,11 @@ module HeimdallTools
48
53
  end
49
54
 
50
55
  def snippet(snippetid)
51
- snippet = @snippets.select { |x| x['@id'].eql?(snippetid) }.first
56
+ snippet = @snippets.select { |x| x['id'].eql?(snippetid) }.first
52
57
  "\nPath: #{snippet['File']}\n" \
53
58
  "StartLine: #{snippet['StartLine']}, " \
54
59
  "EndLine: #{snippet['EndLine']}\n" \
55
- "Code:\n#{snippet['Text'].strip}" \
60
+ "Code:\n#{snippet['Text']['#cdata-section'].strip}" \
56
61
  end
57
62
 
58
63
  def nist_tag(rule)
@@ -68,26 +73,29 @@ module HeimdallTools
68
73
  end
69
74
 
70
75
  def to_hdf
71
- inpsec_json = {}
72
-
73
- inpsec_json['name'] = 'Fortify Static Analyzer Scan'
74
- inpsec_json['version'] = [@timestamp['@date'], @timestamp['@time']].join(' ')
75
- inpsec_json['controls'] = []
76
-
76
+ controls = []
77
77
  @rules.each do |rule|
78
78
  @item = {}
79
- @item['id'] = rule['@classID']
80
- @item['desc'] = rule['Explanation']
81
- @item['title'] = rule['Abstract']
82
- @item['impact'] = impact(rule['@classID'])
83
- @item['code'] = ''
84
- @item['results'] = []
85
- @item['results'] = primaries(@item['id'])
86
- @item['tags'] = {}
87
- @item['tags']['nist'] = [nist_tag(rule).to_s, 'Rev_4']
88
- inpsec_json['controls'] << @item
79
+ @item['id'] = rule['classID']
80
+ @item['desc'] = rule['Explanation']
81
+ @item['title'] = rule['Abstract']
82
+ @item['impact'] = impact(rule['classID'])
83
+ @item['descriptions'] = NA_ARRAY
84
+ @item['refs'] = NA_ARRAY
85
+ @item['source_location'] = NA_HASH
86
+ @item['code'] = NA_TAG
87
+ @item['results'] = []
88
+ @item['results'] = primaries(@item['id'])
89
+ @item['tags'] = {}
90
+ @item['tags']['nist'] = [nist_tag(rule).to_s, 'Rev_4']
91
+ controls << @item
89
92
  end
90
- inpsec_json.to_json
93
+ results = HeimdallDataFormat.new(profile_name: 'Fortify Static Analyzer Scan',
94
+ version: @fortify_version,
95
+ title: 'Fortify Static Analyzer Scan',
96
+ summary: "Fortify Static Analyzer Scan of UUID: #{@uuid}",
97
+ controls: controls)
98
+ results.to_hdf
91
99
  end
92
100
  end
93
101
  end
@@ -0,0 +1,66 @@
1
+ require 'json'
2
+ require 'heimdall_tools/version'
3
+ require 'openssl'
4
+
5
+ NA_TAG = nil.freeze
6
+ NA_ARRAY = [].freeze
7
+ NA_HASH = {}.freeze
8
+ NA_FLOAT = 0.0.freeze
9
+
10
+ PLATFORM_NAME = 'Heimdall Tools'.freeze
11
+
12
+
13
+ module HeimdallTools
14
+ class HeimdallDataFormat
15
+ def initialize(profile_name: NA_TAG,
16
+ version: NA_TAG,
17
+ duration: NA_TAG,
18
+ sha256: NA_TAG,
19
+ title: NA_TAG,
20
+ maintainer: NA_TAG,
21
+ summary: NA_TAG,
22
+ license: NA_TAG,
23
+ copyright: NA_TAG,
24
+ copyright_email: NA_TAG,
25
+ supports: NA_ARRAY,
26
+ attributes: NA_ARRAY,
27
+ depends: NA_ARRAY,
28
+ groups: NA_ARRAY,
29
+ status: 'loaded',
30
+ controls: NA_TAG)
31
+
32
+ @results_json = {}
33
+ @results_json['platform'] = {}
34
+ @results_json['platform']['name'] = 'Heimdall Tools'
35
+ @results_json['platform']['release'] = HeimdallTools::VERSION
36
+ @results_json['version'] = HeimdallTools::VERSION
37
+
38
+ @results_json['statistics'] = {}
39
+ @results_json['statistics']['duration'] = duration || NA_TAG
40
+
41
+ @results_json['profiles'] = []
42
+
43
+ profile_block = {}
44
+ profile_block['name'] = profile_name
45
+ profile_block['version'] = version
46
+ profile_block['title'] = title
47
+ profile_block['maintainer'] = maintainer
48
+ profile_block['summary'] = summary
49
+ profile_block['license'] = license
50
+ profile_block['copyright'] = copyright
51
+ profile_block['copyright_email'] = copyright_email
52
+ profile_block['supports'] = supports
53
+ profile_block['attributes'] = attributes
54
+ profile_block['depends'] = depends
55
+ profile_block['groups'] = groups
56
+ profile_block['status'] = status
57
+ profile_block['controls'] = controls
58
+ profile_block['sha256'] = OpenSSL::Digest::SHA256.digest(profile_block.to_s).unpack("H*")[0]
59
+ @results_json['profiles'] << profile_block
60
+ end
61
+
62
+ def to_hdf
63
+ @results_json.to_json
64
+ end
65
+ end
66
+ end
@@ -2,4 +2,6 @@
2
2
 
3
3
  Examples:
4
4
 
5
- heimdall_tools sonarqube_mapper -n sonar_project -u http://sonar:9000/api -o scan_results.json
5
+ heimdall_tools sonarqube_mapper -n sonar_project_key -u http://sonar:9000/api -o scan_results.json
6
+
7
+ heimdall_tools sonarqube_mapper -n sonar_project_key -u http://sonar:9000/api --auth admin:admin -o scan_results.json
@@ -1,6 +1,7 @@
1
1
  require 'httparty'
2
2
  require 'json'
3
3
  require 'csv'
4
+ require 'heimdall_tools/hdf'
4
5
 
5
6
  MAPPING_FILES = {
6
7
  cwe: './lib/data/cwe-nist-mapping.csv'.freeze,
@@ -16,7 +17,7 @@ IMPACT_MAPPING = {
16
17
  }.freeze
17
18
 
18
19
  def check_response(response)
19
- raise "API Error: #{response.status}\n#{response.body}" unless response.ok?
20
+ raise "API Error: #{response.response}\n#{response.body}" unless response.ok?
20
21
  end
21
22
 
22
23
  class SonarQubeApi
@@ -28,8 +29,20 @@ class SonarQubeApi
28
29
 
29
30
  PAGE_SIZE = 100
30
31
 
31
- def initialize(api_url)
32
+ def initialize(api_url, auth=nil)
32
33
  @api_url = api_url
34
+ @auth = auth
35
+ end
36
+
37
+ def query_api(endpoint, params={})
38
+ creds = {
39
+ username: @auth.split(':')[0],
40
+ password: @auth.split(':')[1]
41
+ } unless @auth.nil?
42
+
43
+ response = HTTParty.get(@api_url + endpoint, { query: params, basic_auth: creds })
44
+ check_response response
45
+ response
33
46
  end
34
47
 
35
48
  # Query issues endpoint, get all vulnerabilities
@@ -45,8 +58,7 @@ class SonarQubeApi
45
58
  }
46
59
 
47
60
  loop do # Get all pages
48
- response = HTTParty.get(@api_url + ISSUES_ENDPOINT, { query: params })
49
- check_response response
61
+ response = query_api(ISSUES_ENDPOINT, params)
50
62
  issues += response['issues']
51
63
 
52
64
  if params[:p] * PAGE_SIZE >= response['paging']['total']
@@ -64,8 +76,7 @@ class SonarQubeApi
64
76
  params = {
65
77
  key: rule
66
78
  }
67
- response = HTTParty.get(@api_url + RULE_ENDPOINT, { query: params })
68
- check_response response
79
+ response = query_api(RULE_ENDPOINT, params)
69
80
  response['rule']
70
81
  end
71
82
 
@@ -80,15 +91,13 @@ class SonarQubeApi
80
91
  params = {
81
92
  key: component
82
93
  }
83
- response = HTTParty.get(@api_url + SOURCE_ENDPOINT, { query: params })
84
- check_response response
94
+ response = query_api(SOURCE_ENDPOINT, params)
85
95
  response.body.split("\n")[start_line..end_line].join("\n")
86
96
  end
87
97
 
88
98
  # Query the version of the SonarQube server
89
99
  def query_version
90
- response = HTTParty.get(@api_url + VERSION_ENDPOINT)
91
- check_response response
100
+ response = query_api(VERSION_ENDPOINT)
92
101
  response.body
93
102
  end
94
103
  end
@@ -96,9 +105,9 @@ end
96
105
  module HeimdallTools
97
106
  class SonarQubeMapper
98
107
  # Fetches the necessary data from the API and builds report
99
- def initialize(project_name, sonarqube_url)
108
+ def initialize(project_name, sonarqube_url, auth=nil)
100
109
  @project_name = project_name
101
- @api = SonarQubeApi.new(sonarqube_url)
110
+ @api = SonarQubeApi.new(sonarqube_url,auth)
102
111
 
103
112
  @mappings = load_nist_mappings
104
113
  @findings = @api.query_issues(@project_name).map { |x| Finding.new(x, @api) }
@@ -119,7 +128,7 @@ module HeimdallTools
119
128
  headers: true,
120
129
  header_converters: :symbol,
121
130
  converters: :all })
122
- mappings[mapping_type] = Hash[csv_data.map { |row|
131
+ mappings[mapping_type] = Hash[csv_data.reject{ |row| row[:nistid].nil? }.map { |row|
123
132
  [row[(mapping_type.to_s.downcase + 'id').to_sym].to_s, [row[:nistid], "Rev_#{row[:rev]}"]]
124
133
  }]
125
134
  end
@@ -128,13 +137,12 @@ module HeimdallTools
128
137
 
129
138
  # Returns a report in HDF format
130
139
  def to_hdf
131
- {
132
- controls: @controls.map(&:hdf),
133
- # currently on heimdall version tag is displayed as time on profile view
134
- # this wil be updated after heimdal update to fix this
135
- version: Time.now.strftime("%a,%d %b %Y %X"),
136
- name: "#{@project_name} SonarQube Scan"
137
- }.to_json
140
+ results = HeimdallDataFormat.new(profile_name: "SonarQube Scan",
141
+ version: @api.query_version,
142
+ title: "SonarQube Scan of Project: #{@project_name}",
143
+ summary: "SonarQube Scan of Project: #{@project_name}",
144
+ controls: @controls.map(&:hdf))
145
+ results.to_hdf
138
146
  end
139
147
  end
140
148
  end
@@ -148,17 +156,20 @@ class Control
148
156
  TAG_DATA[:cwe] = {
149
157
  # Some rules with cwe tag don't have cwe number in description!
150
158
  # Currently only squid:S2658, but it has OWASP tag so we can use that.
151
- regex: 'cwe.mitre.org/data/definitions/([^\.]*)' # Sometimes the "http://" is not part of the url
159
+ regex: 'cwe.mitre.org/data/definitions/(\d*)' # Sometimes the "http://" is not part of the url
152
160
  }
153
161
  TAG_DATA[:owasp] = {
154
162
  # Many (19 currently) owasp have don't cwe (ex. squid:S3355)
155
163
  }
156
- TAG_DATA[:cert] = {
157
- # Some rules only have cert tag (ex. kotlin:S1313)
158
- # Some rules with cert tag don't actually have cert in description!
159
- # Currently only squid:S4434, but it has OWASP tag so we can use that.
160
- regex: 'CERT,?\n? ([^<]*)\.?<'
161
- }
164
+
165
+ # CERT data mapping is deactivated for now until CERT -> NIST 800-53 mapping is available.
166
+ # TAG_DATA[:cert] = {
167
+ # # Some rules only have cert tag (ex. kotlin:S1313)
168
+ # # Some rules with cert tag don't actually have cert in description!
169
+ # # Currently only squid:S4434, but it has OWASP tag so we can use that.
170
+ # regex: 'CERT,?\n? ([^<]*)\.?<'
171
+ # }
172
+
162
173
  # All sans-tagged rules have CWE number, so no need to map SANS
163
174
  # There some tags which we can map directly (ex. denial-of-service)
164
175
  # But there are currently no rules with such a tag that don't have a better tag (ex. cwe)
@@ -237,8 +248,11 @@ class Control
237
248
  nist: get_nist_tags
238
249
  },
239
250
  results: @findings.map(&:get_result),
240
- code: '', # This should be the inspec code for the control, which we don't have
241
- id: @key
251
+ code: NA_TAG, # This should be the inspec code for the control, which we don't have
252
+ id: @key,
253
+ descriptions: NA_ARRAY,
254
+ refs: NA_ARRAY,
255
+ source_location: NA_HASH,
242
256
  }
243
257
  end
244
258
  end
@@ -266,8 +280,10 @@ class Finding
266
280
 
267
281
  snip_html = "StartLine: #{snip_start}, EndLine: #{snip_end}<br>Code:<pre>#{snip}</pre>"
268
282
  {
269
- status: 'failed',
270
- code_desc: "Path:#{component}:#{vuln_start}:#{vuln_end} #{snip_html}"
283
+ status: 'failed',
284
+ code_desc: "Path:#{component}:#{vuln_start}:#{vuln_end} #{snip_html}",
285
+ run_time: NA_FLOAT,
286
+ start_time: Time.now.strftime("%a,%d %b %Y %X")
271
287
  }
272
288
  end
273
289
  end
@@ -1,3 +1,4 @@
1
1
  module HeimdallTools
2
- VERSION = '1.2.0'.freeze
2
+ VERSION = '1.3.20'.freeze
3
3
  end
4
+
@@ -1,6 +1,8 @@
1
1
  require 'json'
2
2
  require 'nokogiri'
3
3
  require 'csv'
4
+ require 'heimdall_tools/hdf'
5
+
4
6
 
5
7
  CWE_NIST_MAPPING_FILE = './lib/data/cwe-nist-mapping.csv'.freeze
6
8
 
@@ -46,6 +48,8 @@ module HeimdallTools
46
48
  finding = {}
47
49
  finding['status'] = 'failed'
48
50
  finding['code_desc'] = format_code_desc(instance)
51
+ finding['run_time'] = NA_FLOAT
52
+ finding['start_time'] = @timestamp
49
53
  finding
50
54
  end
51
55
 
@@ -98,20 +102,17 @@ module HeimdallTools
98
102
  end
99
103
 
100
104
  def to_hdf
101
- inpsec_profile = {}
102
-
103
- inpsec_profile['name'] = "#{@host} OWASP ZAP Scan"
104
- inpsec_profile['version'] = @timestamp
105
-
106
- inpsec_profile['controls'] = []
107
-
105
+ controls = []
108
106
  @alerts.each do |alert|
109
107
  @item = {}
110
108
  @item['id'] = alert[:pluginid].to_s
111
109
  @item['title'] = alert[:name].to_s
112
110
  @item['desc'] = Nokogiri::HTML(alert[:desc]).text
113
- @item['impact'] = impact(alert[:riskcode]).to_s
111
+ @item['impact'] = impact(alert[:riskcode])
114
112
  @item['tags'] = {}
113
+ @item['descriptions'] = NA_ARRAY
114
+ @item['refs'] = NA_ARRAY
115
+ @item['source_location'] = NA_HASH
115
116
  @item['tags']['nist'] = nist_tag(alert[:cweid])
116
117
  @item['tags']['cweid'] = alert[:cweid].to_s
117
118
  @item['tags']['wascid'] = alert[:wascid].to_s
@@ -122,10 +123,16 @@ module HeimdallTools
122
123
  @item['code'] = ''
123
124
  @item['results'] = process_instances(alert[:instances])
124
125
 
125
- inpsec_profile['controls'] << @item
126
+ controls << @item
126
127
  end
127
- fix_duplicates(inpsec_profile['controls'])
128
- inpsec_profile.to_json
128
+ fix_duplicates(controls)
129
+
130
+ results = HeimdallDataFormat.new(profile_name: 'OWASP ZAP Scan',
131
+ version: @zap_verison,
132
+ title: "OWASP ZAP Scan of Host: #{@host}",
133
+ summary: "OWASP ZAP Scan of Host: #{@host}",
134
+ controls: controls)
135
+ results.to_hdf
129
136
  end
130
137
  end
131
138
  end
@@ -0,0 +1,55 @@
1
+ require 'nokogiri'
2
+
3
+ def xml_node_to_hash(node)
4
+ # If we are at the root of the document, start the hash
5
+ if node.element?
6
+ result_hash = {}
7
+ if node.attributes != {}
8
+ attributes = {}
9
+ node.attributes.keys.each do |key|
10
+ attributes[node.attributes[key].name] = node.attributes[key].value
11
+ end
12
+ end
13
+ if !node.children.empty?
14
+ node.children.each do |child|
15
+ result = xml_node_to_hash(child)
16
+
17
+ if child.name == 'text'
18
+ unless child.next_sibling || child.previous_sibling
19
+ return result unless attributes
20
+
21
+ result_hash[child.name] = result
22
+ end
23
+ elsif result_hash[child.name]
24
+
25
+ if result_hash[child.name].is_a?(Object::Array)
26
+ result_hash[child.name] << result
27
+ else
28
+ result_hash[child.name] = [result_hash[child.name]] << result
29
+ end
30
+ else
31
+ result_hash[child.name] = result
32
+ end
33
+ end
34
+ if attributes
35
+ # add code to remove non-data attributes e.g. xml schema, namespace here
36
+ # if there is a collision then node content supersets attributes
37
+ result_hash = attributes.merge(result_hash)
38
+ end
39
+ return result_hash
40
+ else
41
+ return attributes
42
+ end
43
+ else
44
+ node.content.to_s
45
+ end
46
+ end
47
+
48
+ def xml_to_hash(xml)
49
+ begin
50
+ data = Nokogiri::XML(xml) { |config| config.strict }
51
+ rescue Nokogiri::XML::SyntaxError => e
52
+ puts "XML Parsing caught exception: #{e}"
53
+ end
54
+ { data.root.name => xml_node_to_hash(data.root) }
55
+ 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.2.0
4
+ version: 1.3.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Robert Thew
@@ -10,92 +10,106 @@ authors:
10
10
  autorequire:
11
11
  bindir: exe
12
12
  cert_chain: []
13
- date: 2019-02-04 00:00:00.000000000 Z
13
+ date: 2020-03-31 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
- name: activesupport
16
+ name: nokogiri
17
17
  requirement: !ruby/object:Gem::Requirement
18
18
  requirements:
19
- - - ">="
19
+ - - "~>"
20
20
  - !ruby/object:Gem::Version
21
- version: 4.2.3
21
+ version: 1.10.9
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
25
25
  requirements:
26
- - - ">="
26
+ - - "~>"
27
27
  - !ruby/object:Gem::Version
28
- version: 4.2.3
28
+ version: 1.10.9
29
29
  - !ruby/object:Gem::Dependency
30
- name: colorize
30
+ name: thor
31
31
  requirement: !ruby/object:Gem::Requirement
32
32
  requirements:
33
33
  - - "~>"
34
34
  - !ruby/object:Gem::Version
35
- version: '0'
35
+ version: '0.19'
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: '0'
42
+ version: '0.19'
43
43
  - !ruby/object:Gem::Dependency
44
- name: nokogiri
44
+ name: json
45
45
  requirement: !ruby/object:Gem::Requirement
46
46
  requirements:
47
47
  - - "~>"
48
48
  - !ruby/object:Gem::Version
49
- version: '1.8'
49
+ version: '2.3'
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: '1.8'
56
+ version: '2.3'
57
57
  - !ruby/object:Gem::Dependency
58
- name: nori
58
+ name: csv
59
59
  requirement: !ruby/object:Gem::Requirement
60
60
  requirements:
61
61
  - - "~>"
62
62
  - !ruby/object:Gem::Version
63
- version: '0'
63
+ version: '3.1'
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: '0'
70
+ version: '3.1'
71
71
  - !ruby/object:Gem::Dependency
72
- name: OptionParser
72
+ name: httparty
73
73
  requirement: !ruby/object:Gem::Requirement
74
74
  requirements:
75
75
  - - "~>"
76
76
  - !ruby/object:Gem::Version
77
- version: '0'
77
+ version: 0.18.0
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: '0'
84
+ version: 0.18.0
85
85
  - !ruby/object:Gem::Dependency
86
- name: thor
86
+ name: openssl
87
87
  requirement: !ruby/object:Gem::Requirement
88
88
  requirements:
89
89
  - - "~>"
90
90
  - !ruby/object:Gem::Version
91
- version: '0.19'
91
+ version: '2.1'
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: '0.19'
98
+ version: '2.1'
99
+ - !ruby/object:Gem::Dependency
100
+ name: nori
101
+ requirement: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - "~>"
104
+ - !ruby/object:Gem::Version
105
+ version: '2.6'
106
+ type: :runtime
107
+ prerelease: false
108
+ version_requirements: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - "~>"
111
+ - !ruby/object:Gem::Version
112
+ version: '2.6'
99
113
  - !ruby/object:Gem::Dependency
100
114
  name: bundler
101
115
  requirement: !ruby/object:Gem::Requirement
@@ -128,30 +142,44 @@ dependencies:
128
142
  name: pry
129
143
  requirement: !ruby/object:Gem::Requirement
130
144
  requirements:
131
- - - "~>"
145
+ - - ">="
132
146
  - !ruby/object:Gem::Version
133
147
  version: '0'
134
148
  type: :development
135
149
  prerelease: false
136
150
  version_requirements: !ruby/object:Gem::Requirement
137
151
  requirements:
138
- - - "~>"
152
+ - - ">="
153
+ - !ruby/object:Gem::Version
154
+ version: '0'
155
+ - !ruby/object:Gem::Dependency
156
+ name: codeclimate-test-reporter
157
+ requirement: !ruby/object:Gem::Requirement
158
+ requirements:
159
+ - - ">="
160
+ - !ruby/object:Gem::Version
161
+ version: '0'
162
+ type: :development
163
+ prerelease: false
164
+ version_requirements: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - ">="
139
167
  - !ruby/object:Gem::Version
140
168
  version: '0'
141
169
  - !ruby/object:Gem::Dependency
142
170
  name: rake
143
171
  requirement: !ruby/object:Gem::Requirement
144
172
  requirements:
145
- - - "~>"
173
+ - - ">="
146
174
  - !ruby/object:Gem::Version
147
- version: '10.0'
148
- type: :runtime
175
+ version: '0'
176
+ type: :development
149
177
  prerelease: false
150
178
  version_requirements: !ruby/object:Gem::Requirement
151
179
  requirements:
152
- - - "~>"
180
+ - - ">="
153
181
  - !ruby/object:Gem::Version
154
- version: '10.0'
182
+ version: '0'
155
183
  description: Converter utils that can be included as a gem or used from the command
156
184
  line
157
185
  email:
@@ -174,6 +202,7 @@ files:
174
202
  - lib/heimdall_tools/cli.rb
175
203
  - lib/heimdall_tools/command.rb
176
204
  - lib/heimdall_tools/fortify_mapper.rb
205
+ - lib/heimdall_tools/hdf.rb
177
206
  - lib/heimdall_tools/help.rb
178
207
  - lib/heimdall_tools/help/fortify_mapper.md
179
208
  - lib/heimdall_tools/help/sonarqube_mapper.md
@@ -181,7 +210,7 @@ files:
181
210
  - lib/heimdall_tools/sonarqube_mapper.rb
182
211
  - lib/heimdall_tools/version.rb
183
212
  - lib/heimdall_tools/zap_mapper.rb
184
- - lib/utilities/gitkeep
213
+ - lib/utilities/xml_to_hash.rb
185
214
  homepage: https://github.com/mitre/heimdall_tools
186
215
  licenses:
187
216
  - Apache-2.0
@@ -202,8 +231,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
202
231
  - !ruby/object:Gem::Version
203
232
  version: '0'
204
233
  requirements: []
205
- rubyforge_project:
206
- rubygems_version: 2.6.14
234
+ rubygems_version: 3.0.3
207
235
  signing_key:
208
236
  specification_version: 4
209
237
  summary: Convert Forify, Openzap and Sonarqube results to HDF
File without changes