inspec_tools 2.0.4 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +25 -17
- data/Rakefile +82 -8
- data/lib/data/cis_to_nist_critical_controls +0 -0
- data/lib/data/cis_to_nist_mapping +0 -0
- data/lib/happy_mapper_tools/benchmark.rb +83 -0
- data/lib/happy_mapper_tools/stig_attributes.rb +68 -48
- data/lib/inspec_tools/csv.rb +42 -39
- data/lib/inspec_tools/generate_map.rb +35 -0
- data/lib/inspec_tools/inspec.rb +19 -91
- data/lib/inspec_tools/pdf.rb +2 -13
- data/lib/inspec_tools/plugin_cli.rb +22 -53
- data/lib/inspec_tools/summary.rb +108 -76
- data/lib/inspec_tools/xccdf.rb +1 -0
- data/lib/inspec_tools/xlsx_tool.rb +4 -16
- data/lib/utilities/cci_xml.rb +13 -0
- data/lib/utilities/cis_to_nist.rb +11 -0
- data/lib/utilities/inspec_util.rb +10 -74
- data/lib/utilities/mapping_validator.rb +10 -0
- data/lib/utilities/xccdf/from_inspec.rb +89 -0
- data/lib/utilities/xccdf/to_xccdf.rb +388 -0
- data/lib/utilities/xccdf/xccdf_score.rb +116 -0
- metadata +48 -29
- data/CHANGELOG.md +0 -714
- data/lib/data/NIST_Map_02052020_CIS_Controls_Version_7.1_Implementation_Groups_1.2.xlsx +0 -0
- data/lib/data/NIST_Map_09212017B_CSC-CIS_Critical_Security_Controls_VER_6.1_Excel_9.1.2016.xlsx +0 -0
- data/lib/utilities/extract_nist_cis_mapping.rb +0 -57
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 315e07faccf97b313b9493963ef7b9b80ffa7a1459bfa661527c4e827de89676
|
4
|
+
data.tar.gz: e31f0bc2c0006bcb96b9ee46f34c59b8ba71358c2293d7c39874b0fc80b5292b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 50409617c4e6142916f328e5850a5ef3f2d99b9e71671714ce0475708c435242911b6d4455f47fd1f5e50a7778b80e673d4ec74e3ee5d8f66ab5530c42fa8ad9
|
7
|
+
data.tar.gz: e34adf2df0ec1b1bcd5d9224a2621565c5c4efbe79177c2326a3ef8eef6e10922cbc025682c6bade7179add2e59b3b6394419da0cf7c82f1fd8dcfb58efe49f3
|
data/README.md
CHANGED
@@ -65,12 +65,12 @@ For Docker usage, replace the `inspec_tools` command with the correct Docker com
|
|
65
65
|
|
66
66
|
- **On Linux and Mac**: `docker run -it -v$(pwd):/share mitre/inspec_tools`
|
67
67
|
- **On Windows CMD**: `docker run -it -v%cd%:/share mitre/inspec_tools`
|
68
|
-
|
68
|
+
|
69
69
|
Note that all of the above Docker commands will mount your current directory on the Docker container. Ensure that you have navigated to the directory you intend to convert files in before executing the command.
|
70
70
|
|
71
71
|
### generate_map
|
72
72
|
|
73
|
-
This command will generate a `mapping.
|
73
|
+
This command will generate a `mapping.yml` file that can be passed in to the `csv2inspec` command with the `--m` option.
|
74
74
|
|
75
75
|
```
|
76
76
|
USAGE: inspec_tools generate_map
|
@@ -100,13 +100,15 @@ If the specified threshold is not met, an error code (1) is returned along with
|
|
100
100
|
|
101
101
|
The compliance score are rounded down to the nearest whole number. For example a score of 77.3 would be displayed as 77.
|
102
102
|
|
103
|
+
Thresholds provided inline (i.e. `-i`) override thresholds provided by files (i.e. `-f`).
|
104
|
+
|
103
105
|
```
|
104
106
|
USAGE: inspec_tools compliance [OPTIONS] -j <inspec-json> -i <threshold-inline>
|
105
107
|
inspec_tools compliance [OPTIONS] -j <inspec-json> -f <threshold-file>
|
106
108
|
FLAGS:
|
107
109
|
-j --inspec-json <inspec-json> : path to InSpec results Json
|
108
110
|
-i --template-inline <threshold-inline> : inline compliance threshold definition
|
109
|
-
-f --
|
111
|
+
-f --threshold-file <threshold-file> : yaml file with compliance threshold definition
|
110
112
|
Examples:
|
111
113
|
|
112
114
|
inspec_tools compliance -j examples/sample_json/rhel-simp.json -i '{compliance.min: 80, failed.critical.max: 0, failed.high.max: 0}'
|
@@ -135,11 +137,11 @@ failed.high.max: 1
|
|
135
137
|
|
136
138
|
#### In-Line Examples
|
137
139
|
```
|
138
|
-
{compliance: {min: 90}, failed: {critical: {max: 0}, high: {max: 0}}}
|
140
|
+
"{compliance: {min: 90}, failed: {critical: {max: 0}, high: {max: 0}}}"
|
139
141
|
```
|
140
142
|
|
141
143
|
```
|
142
|
-
{compliance.min: 81, failed.critical.max: 0, failed.high.max: 0}
|
144
|
+
"{compliance.min: 81, failed.critical.max: 0, failed.high.max: 0}"
|
143
145
|
```
|
144
146
|
|
145
147
|
## summary
|
@@ -181,16 +183,20 @@ error
|
|
181
183
|
low : 0
|
182
184
|
```
|
183
185
|
|
184
|
-
Using additional flags will override the normal output and only display the output that flag specifies.
|
186
|
+
Using additional flags will override the normal output and only display the output that flag specifies.
|
187
|
+
|
188
|
+
USAGE: inspec_tools summary [OPTIONS] -j <inspec-json>
|
189
|
+
|
190
|
+
Thresholds provided inline (i.e. `-i`) override thresholds provided by files (i.e. `-t`).
|
185
191
|
|
186
|
-
USAGE: inspec_tools summary [OPTIONS] -j <inspec-json>
|
187
192
|
|
188
193
|
```
|
189
194
|
FLAGS:
|
190
|
-
-j --inspec-json <inspec-json>
|
191
|
-
-
|
192
|
-
-
|
193
|
-
-
|
195
|
+
-j --inspec-json <inspec-json> : path to InSpec results JSON
|
196
|
+
-f --json-full, --no-json-full : print the summary STDOUT as JSON
|
197
|
+
-k --json-counts, --no-json-counts : print the result status to STDOUT as JSON
|
198
|
+
-t, --threshold-file=THRESHOLD_FILE] : path to threshold YAML file
|
199
|
+
-i, --threshold-inline=THRESHOLD_INLINE] : string of text representing threshold YAML inline
|
194
200
|
|
195
201
|
Examples:
|
196
202
|
|
@@ -211,7 +217,7 @@ FLAGS:
|
|
211
217
|
-f --format [ruby | hash] : the format you would like (default: ruby) [optional]
|
212
218
|
-s --separate-files [true | false] : output the resulting controls as one or mutiple files (default: true) [optional]
|
213
219
|
-m --metadata <metadata-json> : path to json file with additional metadata for the inspec.yml file [optional]
|
214
|
-
-r --replace-tags <array> : A case-sensitive,
|
220
|
+
-r --replace-tags <array> : A case-sensitive, space separated list to replace tags with a $ if found in a group rules description tag [optional]
|
215
221
|
|
216
222
|
example: inspec_tools xccdf2inspec -x xccdf_file.xml -a attributes.yml -o myprofile -f ruby -s false
|
217
223
|
```
|
@@ -220,16 +226,18 @@ example: inspec_tools xccdf2inspec -x xccdf_file.xml -a attributes.yml -o myprof
|
|
220
226
|
|
221
227
|
`inspec2xccdf` converts an InSpec profile in json format to a STIG XCCDF Document
|
222
228
|
|
229
|
+
See [examples documentation](./examples/inspec2xccdf/README.md) for additional guidance on usage including attribute details.
|
230
|
+
|
223
231
|
```
|
224
232
|
USAGE: inspec_tools inspec2xccdf [OPTIONS] -j <inspec-json> -a <xccdf-attr-yml> -o <xccdf-xml>
|
225
233
|
|
226
234
|
FLAGS:
|
227
235
|
-j --inspec-json <inspec-json> : path to InSpec Json file created using command 'inspec json <profile> > example.json'
|
228
|
-
-a --attributes <xccdf-attr-yml> : path to yml file that provides the required attributes for the XCCDF
|
229
|
-
-o --output <xccdf-xml> : name or path to create the
|
230
|
-
|
236
|
+
-a --attributes <xccdf-attr-yml> : path to yml file that provides the required attributes for the XCCDF document. These attributes are parts of XCCDF document which do not fit into the InSpec schema.
|
237
|
+
-o --output <xccdf-xml> : name or path to create the XCCDF and title to give the XCCDF
|
238
|
+
-m, [--metadata=METADATA] : path to json file with additional host metadata for the XCCDF file
|
231
239
|
|
232
|
-
example: inspec_tools inspec2xccdf -j
|
240
|
+
example: inspec_tools inspec2xccdf -j examples/sample_json/good_nginxresults.json -a lib/data/attributes.yml -o output.xccdf
|
233
241
|
```
|
234
242
|
|
235
243
|
## csv2inspec
|
@@ -295,7 +303,7 @@ FLAGS:
|
|
295
303
|
-s --separate-files [true | false] : output the resulting controls as multiple files (default: true) [optional]
|
296
304
|
-d --debug : debug run [optional]
|
297
305
|
|
298
|
-
example: inspec_tools pdf2inspec -p
|
306
|
+
example: inspec_tools pdf2inspec -p examples/CIS_Ubuntu_Linux_16.04_LTS_Benchmark_v1.0.0.pdf -o /path/to/myprofile -f ruby -s true
|
299
307
|
```
|
300
308
|
|
301
309
|
## xlsx2inspec
|
data/Rakefile
CHANGED
@@ -1,10 +1,9 @@
|
|
1
|
-
require
|
2
|
-
require "rake/testtask"
|
1
|
+
require 'rake/testtask'
|
3
2
|
require File.expand_path('../lib/inspec_tools/version', __FILE__)
|
4
3
|
|
5
4
|
Rake::TestTask.new(:test) do |t|
|
6
|
-
t.libs <<
|
7
|
-
t.libs <<
|
5
|
+
t.libs << 'test'
|
6
|
+
t.libs << 'lib'
|
8
7
|
t.test_files = FileList['test/**/*_test.rb']
|
9
8
|
end
|
10
9
|
|
@@ -20,11 +19,86 @@ namespace :test do
|
|
20
19
|
'test/unit/inspec_tools_test.rb'
|
21
20
|
])
|
22
21
|
end
|
22
|
+
|
23
|
+
Rake::TestTask.new(:exclude_slow) do |t|
|
24
|
+
t.description = 'Excluding all tests that take more than 3 seconds to complete'
|
25
|
+
t.libs << 'test'
|
26
|
+
t.libs << "lib"
|
27
|
+
t.verbose = true
|
28
|
+
t.test_files = FileList['test/**/*_test.rb'].reject{|file| file.include? 'pdf_test.rb'}.reverse
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
desc 'Build for release'
|
33
|
+
task :build_release do
|
34
|
+
|
35
|
+
Rake::Task["generate_mapping_objects"].reenable
|
36
|
+
Rake::Task["generate_mapping_objects"].invoke
|
37
|
+
|
38
|
+
system('gem build inspec_tools.gemspec')
|
39
|
+
end
|
40
|
+
|
41
|
+
desc 'Generate mapping objects'
|
42
|
+
task :generate_mapping_objects do
|
43
|
+
require 'roo'
|
44
|
+
|
45
|
+
nist_mapping_cis_controls = ENV['NIST_MAPPING_CIS_CONTROLS'] || 'NIST_Map_02052020_CIS_Controls_Version_7.1_Implementation_Groups_1.2.xlsx'.freeze
|
46
|
+
nist_mapping_cis_critical_controls = ENV['NIST_MAPPING_CIS_CRITICAL_CONTROLS'] || 'NIST_Map_09212017B_CSC-CIS_Critical_Security_Controls_VER_6.1_Excel_9.1.2016.xlsx'.freeze
|
47
|
+
|
48
|
+
data_root_path = File.join(File.expand_path(__dir__), 'lib', 'data')
|
49
|
+
cis_controls_path = File.join(data_root_path, nist_mapping_cis_controls)
|
50
|
+
cis_critical_controls_path = File.join(data_root_path, nist_mapping_cis_critical_controls)
|
51
|
+
|
52
|
+
raise "#{cis_controls_path} does not exist" unless File.exist?(cis_controls_path)
|
53
|
+
|
54
|
+
raise "#{cis_critical_controls_path} does not exist" unless File.exist?(cis_critical_controls_path)
|
55
|
+
|
56
|
+
marshal_cis_controls(cis_controls_path, data_root_path)
|
57
|
+
marshal_cis_critical_controls(cis_critical_controls_path, data_root_path)
|
23
58
|
end
|
24
59
|
|
25
|
-
|
26
|
-
|
27
|
-
|
60
|
+
def marshal_cis_controls(cis_controls_path, data_root_path)
|
61
|
+
cis_to_nist = {}
|
62
|
+
Roo::Spreadsheet.open(cis_controls_path).sheet(3).each do |row|
|
63
|
+
if row[3].is_a?(Numeric)
|
64
|
+
cis_to_nist[row[3].to_s] = row[0]
|
65
|
+
else
|
66
|
+
cis_to_nist[row[2].to_s] = row[0] unless (row[2] == '') || row[2].to_i.nil?
|
67
|
+
end
|
68
|
+
end
|
69
|
+
output_file = File.new(File.join(data_root_path, 'cis_to_nist_mapping'), 'w')
|
70
|
+
Marshal.dump(cis_to_nist, output_file)
|
71
|
+
output_file.close
|
28
72
|
end
|
29
73
|
|
30
|
-
|
74
|
+
def marshal_cis_critical_controls(cis_critical_controls_path, data_root_path)
|
75
|
+
controls_spreadsheet = Roo::Spreadsheet.open(cis_critical_controls_path)
|
76
|
+
controls_spreadsheet.default_sheet = 'VER 6.1 Controls'
|
77
|
+
headings = {}
|
78
|
+
controls_spreadsheet.row(3).each_with_index { |header, idx| headings[header] = idx }
|
79
|
+
|
80
|
+
nist_ver = 4
|
81
|
+
cis_ver = controls_spreadsheet.row(2)[4].split(' ')[-1]
|
82
|
+
control_count = 1
|
83
|
+
mapping = []
|
84
|
+
((controls_spreadsheet.first_row + 3)..controls_spreadsheet.last_row).each do |row_value|
|
85
|
+
current_row = {}
|
86
|
+
if controls_spreadsheet.row(row_value)[headings['NIST SP 800-53 Control #']].to_s != ''
|
87
|
+
current_row[:nist] = controls_spreadsheet.row(row_value)[headings['NIST SP 800-53 Control #']].to_s
|
88
|
+
else
|
89
|
+
current_row[:nist] = 'Not Mapped'
|
90
|
+
end
|
91
|
+
current_row[:nist_ver] = nist_ver
|
92
|
+
if controls_spreadsheet.row(row_value)[headings['Control']].to_s == ''
|
93
|
+
current_row[:cis] = control_count.to_s
|
94
|
+
control_count += 1
|
95
|
+
else
|
96
|
+
current_row[:cis] = controls_spreadsheet.row(row_value)[headings['Control']].to_s
|
97
|
+
end
|
98
|
+
current_row[:cis_ver] = cis_ver
|
99
|
+
mapping << current_row
|
100
|
+
end
|
101
|
+
output_file = File.new(File.join(data_root_path, 'cis_to_nist_critical_controls'), 'w')
|
102
|
+
Marshal.dump(mapping, output_file)
|
103
|
+
output_file.close
|
104
|
+
end
|
Binary file
|
Binary file
|
@@ -99,6 +99,88 @@ module HappyMapperTools
|
|
99
99
|
element :content, String, tag: 'check-content'
|
100
100
|
end
|
101
101
|
|
102
|
+
class MessageType
|
103
|
+
include HappyMapper
|
104
|
+
attribute :severity, String, tag: 'severity'
|
105
|
+
content :message, String
|
106
|
+
end
|
107
|
+
|
108
|
+
class RuleResultType
|
109
|
+
include HappyMapper
|
110
|
+
attribute :idref, String, tag: 'idref'
|
111
|
+
attribute :severity, String, tag: 'severity'
|
112
|
+
attribute :time, String, tag: 'time'
|
113
|
+
attribute :weight, String, tag: 'weight'
|
114
|
+
element :result, String, tag: 'result'
|
115
|
+
# element override - Not implemented. Does not apply to Inspec execution
|
116
|
+
has_many :ident, Ident, tag: 'ident'
|
117
|
+
# Note: element metadata not implemented at this time
|
118
|
+
has_many :message, MessageType, tag: 'message'
|
119
|
+
has_many :instance, String, tag: 'instance'
|
120
|
+
element :fix, Fix, tag: 'fix'
|
121
|
+
element :check, Check, tag: 'check'
|
122
|
+
end
|
123
|
+
|
124
|
+
class ScoreType
|
125
|
+
include HappyMapper
|
126
|
+
|
127
|
+
def initialize(system, maximum, score)
|
128
|
+
@system = system
|
129
|
+
@maximum = maximum
|
130
|
+
@score = score
|
131
|
+
end
|
132
|
+
|
133
|
+
attribute :system, String, tag: 'system'
|
134
|
+
attribute :maximum, String, tag: 'maximum' # optional attribute
|
135
|
+
content :score, String
|
136
|
+
end
|
137
|
+
|
138
|
+
class CPE2idrefType
|
139
|
+
include HappyMapper
|
140
|
+
attribute :idref, String, tag: 'idref'
|
141
|
+
end
|
142
|
+
|
143
|
+
class IdentityType
|
144
|
+
include HappyMapper
|
145
|
+
attribute :authenticated, Boolean, tag: 'authenticated'
|
146
|
+
attribute :privileged, Boolean, tag: 'privileged'
|
147
|
+
content :identity, String
|
148
|
+
end
|
149
|
+
|
150
|
+
class Fact
|
151
|
+
include HappyMapper
|
152
|
+
attribute :name, String, tag: 'name'
|
153
|
+
attribute :type, String, tag: 'type'
|
154
|
+
content :fact, String
|
155
|
+
end
|
156
|
+
|
157
|
+
class TargetFact
|
158
|
+
include HappyMapper
|
159
|
+
has_many :fact, Fact, tag: 'fact'
|
160
|
+
end
|
161
|
+
|
162
|
+
class TestResult
|
163
|
+
include HappyMapper
|
164
|
+
# Note: element benchmark not implemented at this time since this is same file
|
165
|
+
# Note: element title not implemented due to no mapping from Chef Inspec
|
166
|
+
element :remark, String, tag: 'remark'
|
167
|
+
has_many :organization, String, tag: 'organization'
|
168
|
+
element :identity, IdentityType, tag: 'identity'
|
169
|
+
element :target, String, tag: 'target'
|
170
|
+
has_many :target_address, String, tag: 'target-address'
|
171
|
+
element :target_facts, TargetFact, tag: 'target-facts'
|
172
|
+
element :platform, CPE2idrefType, tag: 'platform'
|
173
|
+
# Note: element profile not implemented since Benchmark profile is also not implemented
|
174
|
+
has_many :rule_result, RuleResultType, tag: 'rule-result'
|
175
|
+
has_many :score, ScoreType, tag: 'score' # One minimum
|
176
|
+
# Note: element signature not implemented due to no mapping from Chef Inspec
|
177
|
+
attribute :id, String, tag: 'id'
|
178
|
+
attribute :starttime, String, tag: 'start-time'
|
179
|
+
attribute :endtime, String, tag: 'end-time'
|
180
|
+
# Note: attribute test-system not implemented at this time due to unknown CPE value for Chef Inspec
|
181
|
+
attribute :version, String, tag: 'version'
|
182
|
+
end
|
183
|
+
|
102
184
|
# Class Profile maps from the 'Profile' from Benchmark XML file using HappyMapper
|
103
185
|
class Profile
|
104
186
|
include HappyMapper
|
@@ -156,6 +238,7 @@ module HappyMapperTools
|
|
156
238
|
element :version, String, tag: 'version'
|
157
239
|
has_many :profile, Profile, tag: 'Profile'
|
158
240
|
has_many :group, Group, tag: 'Group'
|
241
|
+
element :testresult, TestResult, tag: 'TestResult'
|
159
242
|
end
|
160
243
|
end
|
161
244
|
end
|
@@ -38,6 +38,7 @@ module HappyMapperTools
|
|
38
38
|
element :documentable, Boolean, tag: 'Documentable'
|
39
39
|
element :mitigations, String, tag: 'Mitigations'
|
40
40
|
element :severity_override_guidance, String, tag: 'SeverityOverrideGuidance'
|
41
|
+
element :security_override_guidance, String, tag: 'SecurityOverrideGuidance'
|
41
42
|
element :potential_impacts, String, tag: 'PotentialImpacts'
|
42
43
|
element :third_party_tools, String, tag: 'ThirdPartyTools'
|
43
44
|
element :mitigation_controls, String, tag: 'MitigationControl'
|
@@ -53,7 +54,8 @@ module HappyMapperTools
|
|
53
54
|
|
54
55
|
detail_tags = %i(vuln_discussion false_positives false_negatives documentable
|
55
56
|
mitigations severity_override_guidance potential_impacts
|
56
|
-
third_party_tools mitigation_controls responsibility ia_controls
|
57
|
+
third_party_tools mitigation_controls responsibility ia_controls
|
58
|
+
security_override_guidance)
|
57
59
|
|
58
60
|
detail_tags.each do |name|
|
59
61
|
define_method name do
|
@@ -140,57 +142,75 @@ module HappyMapperTools
|
|
140
142
|
end
|
141
143
|
|
142
144
|
class DescriptionDetailsType
|
143
|
-
|
144
|
-
|
145
|
-
|
145
|
+
class << self
|
146
|
+
def type
|
147
|
+
DescriptionDetails
|
148
|
+
end
|
146
149
|
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
if offending_tags.count > 1
|
162
|
-
puts "\n\nThe non-standard tags: #{offending_tags.to_s.colorize(:red)}" \
|
163
|
-
' were found in: ' + "\n\n#{value}"
|
164
|
-
else
|
165
|
-
puts "\n\nThe non-standard tag: #{offending_tags.to_s.colorize(:red)}" \
|
166
|
-
' was found in: ' + "\n\n#{value}"
|
150
|
+
def apply(value)
|
151
|
+
value = value.gsub('&', 'and')
|
152
|
+
DescriptionDetails.parse "<Details>#{value}</Details>"
|
153
|
+
rescue Nokogiri::XML::SyntaxError => e
|
154
|
+
if e.to_s.include?('StartTag')
|
155
|
+
report_invalid_start_tag(value, e)
|
156
|
+
else
|
157
|
+
report_disallowed_tags(value)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def apply?(value, _convert_to_type)
|
162
|
+
value.is_a?(String)
|
167
163
|
end
|
168
|
-
puts "\n\nPlease:\n "
|
169
|
-
option_one = '(1) ' + '(best)'.colorize(:green) + ' Use the ' +
|
170
|
-
'`-r --replace-tags array` '.colorize(:light_yellow) +
|
171
|
-
'(case sensitive) option to replace the offending tags ' \
|
172
|
-
'during processing of the XCCDF ' \
|
173
|
-
'file to use the ' +
|
174
|
-
"`$#{offending_tags[0]}` " .colorize(:light_green) +
|
175
|
-
'syntax in your InSpec profile.'
|
176
|
-
option_two = '(2) Update your XCCDF file to *not use* non-standard XCCDF ' \
|
177
|
-
'elements within ' +
|
178
|
-
'`<`,`>`, `<` '.colorize(:red) +
|
179
|
-
'or '.colorize(:default) +
|
180
|
-
'`>` '.colorize(:red) +
|
181
|
-
'as "placeholders", and use something that doesn\'t confuse ' \
|
182
|
-
'the XML parser, such as : ' +
|
183
|
-
"`$#{offending_tags[0]}`" .colorize(:light_green)
|
184
|
-
puts option_one
|
185
|
-
puts "\n"
|
186
|
-
puts option_two
|
187
|
-
# exit
|
188
|
-
end
|
189
164
|
|
190
|
-
|
191
|
-
|
165
|
+
private
|
166
|
+
|
167
|
+
def report_invalid_start_tag(value, error)
|
168
|
+
puts error.to_s.colorize(:red)
|
169
|
+
column = error.column - '<Details>'.length - 2
|
170
|
+
puts "Error around #{value[column-10..column+10].colorize(:light_yellow)}"
|
171
|
+
exit(1)
|
172
|
+
end
|
173
|
+
|
174
|
+
def report_disallowed_tags(value)
|
175
|
+
allowed_tags = %w{VulnDiscussion FalsePositives FalseNegatives Documentable
|
176
|
+
Mitigations SeverityOverrideGuidance PotentialImpacts
|
177
|
+
PotentialImpacts ThirdPartyTools MitigationControl
|
178
|
+
Responsibility IAControl SecurityOverrideGuidance}
|
179
|
+
|
180
|
+
tags_found = value.scan(%r{(?<=<)([^\/]*?)((?= \/>)|(?=>))}).to_a
|
181
|
+
|
182
|
+
tags_found = tags_found.uniq.flatten.reject!(&:empty?)
|
183
|
+
offending_tags = tags_found - allowed_tags
|
184
|
+
|
185
|
+
if offending_tags.count > 1
|
186
|
+
puts "\n\nThe non-standard tags: #{offending_tags.to_s.colorize(:red)}" \
|
187
|
+
' were found in: ' + "\n\n#{value}"
|
188
|
+
else
|
189
|
+
puts "\n\nThe non-standard tag: #{offending_tags.to_s.colorize(:red)}" \
|
190
|
+
' was found in: ' + "\n\n#{value}"
|
191
|
+
end
|
192
|
+
puts "\n\nPlease:\n "
|
193
|
+
option_one = '(1) ' + '(best)'.colorize(:green) + ' Use the ' +
|
194
|
+
'`-r --replace-tags array` '.colorize(:light_yellow) +
|
195
|
+
'(case sensitive) option to replace the offending tags ' \
|
196
|
+
'during processing of the XCCDF ' \
|
197
|
+
'file to use the ' +
|
198
|
+
"`$#{offending_tags[0]}` " .colorize(:light_green) +
|
199
|
+
'syntax in your InSpec profile.'
|
200
|
+
option_two = '(2) Update your XCCDF file to *not use* non-standard XCCDF ' \
|
201
|
+
'elements within ' +
|
202
|
+
'`<`,`>`, `<` '.colorize(:red) +
|
203
|
+
'or '.colorize(:default) +
|
204
|
+
'`>` '.colorize(:red) +
|
205
|
+
'as "placeholders", and use something that doesn\'t confuse ' \
|
206
|
+
'the XML parser, such as : ' +
|
207
|
+
"`$#{offending_tags[0]}`" .colorize(:light_green)
|
208
|
+
puts option_one
|
209
|
+
puts "\n"
|
210
|
+
puts option_two
|
211
|
+
end
|
192
212
|
end
|
213
|
+
HappyMapper::SupportedTypes.register DescriptionDetailsType
|
193
214
|
end
|
194
|
-
HappyMapper::SupportedTypes.register DescriptionDetailsType
|
195
215
|
end
|
196
216
|
end
|