cve_schema 0.1.0
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 +7 -0
- data/.document +3 -0
- data/.github/workflows/ruby.yml +28 -0
- data/.gitignore +6 -0
- data/.rspec +1 -0
- data/.yardopts +1 -0
- data/ChangeLog.md +26 -0
- data/Gemfile +14 -0
- data/LICENSE.txt +20 -0
- data/README.md +50 -0
- data/Rakefile +23 -0
- data/benchmark.rb +47 -0
- data/cve_schema.gemspec +61 -0
- data/gemspec.yml +19 -0
- data/lib/cve_schema.rb +2 -0
- data/lib/cve_schema/cve.rb +257 -0
- data/lib/cve_schema/cve/affects.rb +55 -0
- data/lib/cve_schema/cve/configuration.rb +14 -0
- data/lib/cve_schema/cve/credit.rb +14 -0
- data/lib/cve_schema/cve/data_meta.rb +185 -0
- data/lib/cve_schema/cve/description.rb +24 -0
- data/lib/cve_schema/cve/exploit.rb +14 -0
- data/lib/cve_schema/cve/has_lang_value.rb +93 -0
- data/lib/cve_schema/cve/id.rb +79 -0
- data/lib/cve_schema/cve/impact.rb +75 -0
- data/lib/cve_schema/cve/impact/cvss_v2.rb +318 -0
- data/lib/cve_schema/cve/impact/cvss_v3.rb +388 -0
- data/lib/cve_schema/cve/na.rb +8 -0
- data/lib/cve_schema/cve/problem_type.rb +56 -0
- data/lib/cve_schema/cve/product.rb +79 -0
- data/lib/cve_schema/cve/reference.rb +82 -0
- data/lib/cve_schema/cve/solution.rb +14 -0
- data/lib/cve_schema/cve/source.rb +75 -0
- data/lib/cve_schema/cve/timeline.rb +65 -0
- data/lib/cve_schema/cve/timestamp.rb +25 -0
- data/lib/cve_schema/cve/vendor.rb +83 -0
- data/lib/cve_schema/cve/version.rb +126 -0
- data/lib/cve_schema/cve/work_around.rb +14 -0
- data/lib/cve_schema/exceptions.rb +20 -0
- data/lib/cve_schema/version.rb +6 -0
- data/spec/affects_spec.rb +28 -0
- data/spec/configuration_spec.rb +6 -0
- data/spec/credit_spec.rb +6 -0
- data/spec/cve_schema_spec.rb +8 -0
- data/spec/cve_spec.rb +414 -0
- data/spec/data_meta_spec.rb +167 -0
- data/spec/description.rb +24 -0
- data/spec/exploit_spec.rb +6 -0
- data/spec/fixtures/CVE-2020-1994.json +140 -0
- data/spec/fixtures/CVE-2020-2005.json +152 -0
- data/spec/fixtures/CVE-2020-2050.json +233 -0
- data/spec/fixtures/CVE-2020-4700.json +99 -0
- data/spec/has_lang_value_spec.rb +56 -0
- data/spec/id_spec.rb +91 -0
- data/spec/impact/cvss_v3_spec.rb +118 -0
- data/spec/impact_spec.rb +45 -0
- data/spec/na_spec.rb +14 -0
- data/spec/problem_type_spec.rb +26 -0
- data/spec/product_spec.rb +73 -0
- data/spec/reference_spec.rb +70 -0
- data/spec/shared_examples.rb +19 -0
- data/spec/solution_spec.rb +6 -0
- data/spec/source_spec.rb +84 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/timeline_spec.rb +86 -0
- data/spec/timestamp_spec.rb +24 -0
- data/spec/vendor_spec.rb +73 -0
- data/spec/version_spec.rb +104 -0
- data/spec/work_around_spec.rb +6 -0
- metadata +133 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'cve_schema/cve/impact/cvss_v2'
|
2
|
+
require 'cve_schema/cve/impact/cvss_v3'
|
3
|
+
|
4
|
+
module CVESchema
|
5
|
+
class CVE
|
6
|
+
class Impact
|
7
|
+
|
8
|
+
# @return [CVSSv2, nil]
|
9
|
+
attr_reader :cvssv2
|
10
|
+
|
11
|
+
alias cvss_v2 cvssv2
|
12
|
+
|
13
|
+
# @return [CVSSv3, nil]
|
14
|
+
attr_reader :cvssv3
|
15
|
+
|
16
|
+
alias cvss_v3 cvssv3
|
17
|
+
|
18
|
+
#
|
19
|
+
# Initializes the impact object.
|
20
|
+
#
|
21
|
+
# @param [CVSSv2, nil] cvssv2
|
22
|
+
# The CVSSv2 object.
|
23
|
+
#
|
24
|
+
# @param [CVSSv3, nil] cvssv3
|
25
|
+
# The CVSSv3 object.
|
26
|
+
#
|
27
|
+
def initialize(cvssv2: nil, cvssv3: nil)
|
28
|
+
@cvssv2 = cvssv2
|
29
|
+
@cvssv3 = cvssv3
|
30
|
+
end
|
31
|
+
|
32
|
+
#
|
33
|
+
# Maps the parsed JSON to a Symbol Hash for {#initialize}.
|
34
|
+
#
|
35
|
+
# @param [Hash{String => Object}] json
|
36
|
+
# The parsed JSON.
|
37
|
+
#
|
38
|
+
# @return [Hash{Symbol => Object}]
|
39
|
+
# The mapped Symbol Hash.
|
40
|
+
#
|
41
|
+
# @api semipublic
|
42
|
+
#
|
43
|
+
def self.from_json(json)
|
44
|
+
# HACK: the "impact" value is often an Array containing a single Hash
|
45
|
+
hash = case json
|
46
|
+
when Hash then json
|
47
|
+
when Array then json[0]
|
48
|
+
else
|
49
|
+
raise(InvalidJSON,'"impact" is neither a Hash or Array')
|
50
|
+
end
|
51
|
+
|
52
|
+
{
|
53
|
+
cvssv2: hash['cvssv2'] && CVSSv2.load(hash['cvssv2']),
|
54
|
+
cvssv3: hash['cvssv3'] && CVSSv3.load(hash['cvssv3'])
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
#
|
59
|
+
# Loads the impact object from the parsed JSON.
|
60
|
+
#
|
61
|
+
# @param [Hash{String => Object}] json
|
62
|
+
# The parsed JSON.
|
63
|
+
#
|
64
|
+
# @return [Impact]
|
65
|
+
# The loaded impact object.
|
66
|
+
#
|
67
|
+
# @api semipublic
|
68
|
+
#
|
69
|
+
def self.load(json)
|
70
|
+
new(**from_json(json))
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,318 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CVESchema
|
4
|
+
class CVE
|
5
|
+
class Impact
|
6
|
+
class CVSSv2
|
7
|
+
|
8
|
+
class BM
|
9
|
+
|
10
|
+
AV = {'L' => :L, 'A' => :A, 'N' => :N}
|
11
|
+
|
12
|
+
# The Access Vector.
|
13
|
+
#
|
14
|
+
# @return [:L, :A, :N]
|
15
|
+
attr_reader :av
|
16
|
+
|
17
|
+
AC = {'H' => :H, 'M' => :M, 'L' => :L}
|
18
|
+
|
19
|
+
# The Access Complexity.
|
20
|
+
#
|
21
|
+
# @return [:H, :M, :L]
|
22
|
+
attr_reader :ac
|
23
|
+
|
24
|
+
AU = {'M' => :M, 'S' => :S, 'N' => :N}
|
25
|
+
|
26
|
+
# The Authentication
|
27
|
+
#
|
28
|
+
# @return [:M, :S, :N]
|
29
|
+
attr_reader :au
|
30
|
+
|
31
|
+
C = {'N' => :N, 'P' => :P, 'C' => :C}
|
32
|
+
|
33
|
+
# The Confidentiality impact.
|
34
|
+
#
|
35
|
+
# @return [:N, :P, :C]
|
36
|
+
attr_reader :c
|
37
|
+
|
38
|
+
I = {'N' => :N, 'P' => :P, 'C' => :C}
|
39
|
+
|
40
|
+
# The Integrity impact.
|
41
|
+
#
|
42
|
+
# @return [:N, :P, :C]
|
43
|
+
attr_reader :i
|
44
|
+
|
45
|
+
A = {'N' => :N, 'P' => :P, 'C' => :C}
|
46
|
+
|
47
|
+
# The Availability impact.
|
48
|
+
#
|
49
|
+
# @return [:N, :P, :C]
|
50
|
+
attr_reader :a
|
51
|
+
|
52
|
+
# The CVSSv2 Base Metrics Group score assuming all elements are present.
|
53
|
+
#
|
54
|
+
# @return [String]
|
55
|
+
attr_reader :score
|
56
|
+
|
57
|
+
def initialize(av: nil, ac: nil, au: nil, c: nil, i: nil, a: nil,
|
58
|
+
score: nil)
|
59
|
+
@av = av
|
60
|
+
@ac = ac
|
61
|
+
@c = c
|
62
|
+
@i = i
|
63
|
+
@a = a
|
64
|
+
@score = score
|
65
|
+
end
|
66
|
+
|
67
|
+
#
|
68
|
+
# Maps the parsed JSON to a Symbol Hash for {#initialize}.
|
69
|
+
#
|
70
|
+
# @param [Hash{String => Object}] json
|
71
|
+
# The parsed JSON.
|
72
|
+
#
|
73
|
+
# @return [Hash{Symbol => Object}]
|
74
|
+
# The mapped Symbol Hash.
|
75
|
+
#
|
76
|
+
def self.from_json(json)
|
77
|
+
{
|
78
|
+
av: AV[json['AV']],
|
79
|
+
ac: AC[json['AC']],
|
80
|
+
au: AU[json['AU']],
|
81
|
+
c: C[json['C']],
|
82
|
+
i: I[json['I']],
|
83
|
+
a: A[json['A']],
|
84
|
+
|
85
|
+
score: json['SCORE']
|
86
|
+
}
|
87
|
+
end
|
88
|
+
|
89
|
+
#
|
90
|
+
# Loads the BM object from the parsed JSON.
|
91
|
+
#
|
92
|
+
# @param [Hash{String => Object}] json
|
93
|
+
# The parsed JSON.
|
94
|
+
#
|
95
|
+
# @return [self]
|
96
|
+
# The loaded BM object.
|
97
|
+
#
|
98
|
+
def self.load(json)
|
99
|
+
new(**from_json(json))
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
# @return [BM, nil]
|
105
|
+
attr_reader :bm
|
106
|
+
|
107
|
+
class TM
|
108
|
+
|
109
|
+
E = {'U' => :U, 'POC' => :POC, 'F' => :F, 'H' => :H, 'ND' => :ND}
|
110
|
+
|
111
|
+
# Exploitability
|
112
|
+
#
|
113
|
+
# @return [:U, :POC, :F, :H, :ND]
|
114
|
+
attr_reader :e
|
115
|
+
|
116
|
+
RL = {'OF' => :OF, 'TF' => :TF, 'W' => :W, 'U' => :U, 'ND' => :ND}
|
117
|
+
|
118
|
+
# Remediation Level.
|
119
|
+
#
|
120
|
+
# @return [:OF, :TF, :W, :U, :ND]
|
121
|
+
attr_reader :rl
|
122
|
+
|
123
|
+
RC = {'UC' => :UC, 'UR' => :UR, 'C' => :C, 'ND' => :ND}
|
124
|
+
|
125
|
+
# Report Confidence.
|
126
|
+
#
|
127
|
+
# @return [:UC, :UR, :C, :ND]
|
128
|
+
attr_reader :rc
|
129
|
+
|
130
|
+
# The CVSSv2 Temporal Metrics Group score assuming all elements are present.
|
131
|
+
#
|
132
|
+
# @return [String, nil]
|
133
|
+
attr_reader :score
|
134
|
+
|
135
|
+
def initialize(e: nil, rl: nil, rc: nil, score: nil)
|
136
|
+
@e = e
|
137
|
+
@rl = rl
|
138
|
+
@rc = rc
|
139
|
+
@score = score
|
140
|
+
end
|
141
|
+
|
142
|
+
#
|
143
|
+
# Maps the parsed JSON to a Symbol Hash for {#initialize}.
|
144
|
+
#
|
145
|
+
# @param [Hash{String => Object}] json
|
146
|
+
# The parsed JSON.
|
147
|
+
#
|
148
|
+
# @return [Hash{Symbol => Object}]
|
149
|
+
# The mapped Symbol Hash.
|
150
|
+
#
|
151
|
+
def self.from_json(json)
|
152
|
+
{
|
153
|
+
e: E[json['E']],
|
154
|
+
rl: RL[json['RL']],
|
155
|
+
rc: RC[json['RC']],
|
156
|
+
|
157
|
+
score: json['SCORE']
|
158
|
+
}
|
159
|
+
end
|
160
|
+
|
161
|
+
#
|
162
|
+
# Loads the TM object from the parsed JSON.
|
163
|
+
#
|
164
|
+
# @param [Hash{String => Object}] json
|
165
|
+
# The parsed JSON.
|
166
|
+
#
|
167
|
+
# @return [self]
|
168
|
+
# The loaded TM object.
|
169
|
+
#
|
170
|
+
def self.load(json)
|
171
|
+
new(**from_json(json))
|
172
|
+
end
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
# The Temporal Metrics Group.
|
177
|
+
#
|
178
|
+
# @return [TM, nil]
|
179
|
+
attr_reader :tm
|
180
|
+
|
181
|
+
class EM
|
182
|
+
|
183
|
+
CDP = {
|
184
|
+
'N' => :N,
|
185
|
+
'L' => :L,
|
186
|
+
'LM' => :LM,
|
187
|
+
'MH' => :MH,
|
188
|
+
'H' => :H,
|
189
|
+
'ND' => :ND
|
190
|
+
}
|
191
|
+
|
192
|
+
# The Collateral Damage Potential.
|
193
|
+
#
|
194
|
+
# @return [:N, :L, :LM, :MH, :H, :ND]
|
195
|
+
attr_reader :cdp
|
196
|
+
|
197
|
+
TD = {'N' => :N, 'L' => :L, 'M' => :M, 'H' => :H, 'ND' => :ND}
|
198
|
+
|
199
|
+
# The Target Distribution.
|
200
|
+
#
|
201
|
+
# @return [:N, :L, :M, :H, :ND]
|
202
|
+
attr_reader :td
|
203
|
+
|
204
|
+
CR = {'L' => :L, 'M' => :M, 'H' => :H, 'ND' => :ND}
|
205
|
+
|
206
|
+
# Security Requirements Confidentiality.
|
207
|
+
#
|
208
|
+
# @return [:L, :M, :H, :ND]
|
209
|
+
attr_reader :cr
|
210
|
+
|
211
|
+
IR = {'L' => :L, 'M' => :M, 'H' => :H, 'ND' => :ND}
|
212
|
+
|
213
|
+
# Security Requirements Integrity.
|
214
|
+
#
|
215
|
+
# @return [:L, :M, :H, :ND]
|
216
|
+
attr_reader :ir
|
217
|
+
|
218
|
+
AR = {'L' => :L, 'M' => :M, 'H' => :H, 'ND' => :ND}
|
219
|
+
|
220
|
+
# Security Requirements Availability.
|
221
|
+
#
|
222
|
+
# @return [:L, :M, :H, :ND]
|
223
|
+
attr_reader :ar
|
224
|
+
|
225
|
+
def initialize(cdp: nil, td: nil, cr: nil, ir: nil, ar: nil)
|
226
|
+
@cdp = cdp
|
227
|
+
@td = td
|
228
|
+
@cr = cr
|
229
|
+
@ir = ir
|
230
|
+
@ar = ar
|
231
|
+
end
|
232
|
+
|
233
|
+
#
|
234
|
+
# Maps the parsed JSON to a Symbol Hash for {#initialize}.
|
235
|
+
#
|
236
|
+
# @param [Hash{String => Object}] json
|
237
|
+
# The parsed JSON.
|
238
|
+
#
|
239
|
+
# @return [Hash{Symbol => Object}]
|
240
|
+
# The mapped Symbol Hash.
|
241
|
+
#
|
242
|
+
def self.from_json(json)
|
243
|
+
{
|
244
|
+
cdp: CDP[json['CDP']],
|
245
|
+
td: TD[json['TD']],
|
246
|
+
cr: CR[json['CR']],
|
247
|
+
ir: IR[json['IR']],
|
248
|
+
ar: AR[json['AR']]
|
249
|
+
}
|
250
|
+
end
|
251
|
+
|
252
|
+
#
|
253
|
+
# Loads the EM object from the parsed JSON.
|
254
|
+
#
|
255
|
+
# @param [Hash{String => Object}] json
|
256
|
+
# The parsed JSON.
|
257
|
+
#
|
258
|
+
# @return [self]
|
259
|
+
# The loaded EM object.
|
260
|
+
#
|
261
|
+
def self.load(json)
|
262
|
+
new(**from_json(json))
|
263
|
+
end
|
264
|
+
|
265
|
+
end
|
266
|
+
|
267
|
+
# @return [EM, nil]
|
268
|
+
attr_reader :em
|
269
|
+
|
270
|
+
#
|
271
|
+
# Initializes the CVSSv2.
|
272
|
+
#
|
273
|
+
# @param [BM, nil] bm
|
274
|
+
#
|
275
|
+
# @param [TM, nil] tm
|
276
|
+
#
|
277
|
+
# @param [EM, nil] em
|
278
|
+
#
|
279
|
+
def initialize(bm: nil, tm: nil, em: nil)
|
280
|
+
@bm = bm
|
281
|
+
@tm = tm
|
282
|
+
@em = em
|
283
|
+
end
|
284
|
+
|
285
|
+
#
|
286
|
+
# Maps the parsed JSON to a Symbol Hash for {#initialize}.
|
287
|
+
#
|
288
|
+
# @param [Hash{String => Object}] json
|
289
|
+
# The parsed JSON.
|
290
|
+
#
|
291
|
+
# @return [Hash{Symbol => Object}]
|
292
|
+
# the mapped Symbol Hash.
|
293
|
+
#
|
294
|
+
def self.from_json(json)
|
295
|
+
{
|
296
|
+
bm: json['BM'] && BM.load(json['BM']),
|
297
|
+
tm: json['TM'] && TM.load(json['TM']),
|
298
|
+
em: json['EM'] && EM.load(json['EM']),
|
299
|
+
}
|
300
|
+
end
|
301
|
+
|
302
|
+
#
|
303
|
+
# Loads the CVSSv2 object from the parsed JSON.
|
304
|
+
#
|
305
|
+
# @param [Hash{String => Object}] json
|
306
|
+
# The parsed JSON.
|
307
|
+
#
|
308
|
+
# @return [self]
|
309
|
+
# The loaded CVSSv2 object.
|
310
|
+
#
|
311
|
+
def self.load(json)
|
312
|
+
new(**from_json(json))
|
313
|
+
end
|
314
|
+
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
318
|
+
end
|
@@ -0,0 +1,388 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CVESchema
|
4
|
+
class CVE
|
5
|
+
class Impact
|
6
|
+
class CVSSv3
|
7
|
+
|
8
|
+
#
|
9
|
+
# The Base Metric Group scoring information.
|
10
|
+
#
|
11
|
+
class BM
|
12
|
+
|
13
|
+
AV = {'N' => :N, 'A' => :A, 'L' => :L, 'P' => :P}
|
14
|
+
|
15
|
+
# The Attack Vector.
|
16
|
+
#
|
17
|
+
# @return [:N, :A, :L, :P]
|
18
|
+
attr_reader :av
|
19
|
+
|
20
|
+
AC = {'L' => :L, 'H' => :H}
|
21
|
+
|
22
|
+
# The Attack Complexity.
|
23
|
+
#
|
24
|
+
# @return [:L, :H]
|
25
|
+
attr_reader :ac
|
26
|
+
|
27
|
+
PR = {'N' => :N, 'L' => :L, 'H' => :H}
|
28
|
+
|
29
|
+
# The Privileges Required.
|
30
|
+
#
|
31
|
+
# @return [:N, :L, :H]
|
32
|
+
attr_reader :pr
|
33
|
+
|
34
|
+
UI = {'N' => :N, 'R' => :R}
|
35
|
+
|
36
|
+
# The User Interaction.
|
37
|
+
#
|
38
|
+
# @return [:N, :R]
|
39
|
+
attr_reader :ui
|
40
|
+
|
41
|
+
S = {'U' => :U, 'C' => :C}
|
42
|
+
|
43
|
+
# The Scope
|
44
|
+
#
|
45
|
+
# @return [:U, :C]
|
46
|
+
attr_reader :s
|
47
|
+
|
48
|
+
C = {'H' => :H, 'L' => :L, 'N' => :N}
|
49
|
+
|
50
|
+
# The Confidentiality Impact.
|
51
|
+
#
|
52
|
+
# @return [:H, :L, :N]
|
53
|
+
attr_reader :c
|
54
|
+
|
55
|
+
I = {'H' => :H, 'L' => :L, 'N' => :N}
|
56
|
+
|
57
|
+
# The Integrity Impact
|
58
|
+
#
|
59
|
+
# @return [:H, :L, :N]
|
60
|
+
attr_reader :i
|
61
|
+
|
62
|
+
A = {'H' => :H, 'L' => :L, 'N' => :N}
|
63
|
+
|
64
|
+
# The Availability Impact
|
65
|
+
#
|
66
|
+
# @return [:H, :L, :N]
|
67
|
+
attr_reader :a
|
68
|
+
|
69
|
+
# The CVSSv3 score.
|
70
|
+
#
|
71
|
+
# @return [String]
|
72
|
+
attr_reader :score
|
73
|
+
|
74
|
+
#
|
75
|
+
# Initializes the BM object.
|
76
|
+
#
|
77
|
+
def initialize(av: nil, ac: nil, pr: nil, ui: nil, s: nil, c: nil,
|
78
|
+
i: nil, a: nil, score: nil)
|
79
|
+
@av = av
|
80
|
+
@ac = ac
|
81
|
+
@pr = pr
|
82
|
+
@ui = ui
|
83
|
+
@s = s
|
84
|
+
@c = c
|
85
|
+
@i = i
|
86
|
+
@a = a
|
87
|
+
|
88
|
+
@score = score
|
89
|
+
end
|
90
|
+
|
91
|
+
#
|
92
|
+
# Maps the parsed JSON to a Symbol Hash for {#initialize}.
|
93
|
+
#
|
94
|
+
# @param [Hash{String => Object}] json
|
95
|
+
# The parsed JSON.
|
96
|
+
#
|
97
|
+
# @return [Hash{Symbol => Object}]
|
98
|
+
# The mapped Symbol Hash.
|
99
|
+
#
|
100
|
+
def self.from_json(json)
|
101
|
+
{
|
102
|
+
av: AV[json['AV']],
|
103
|
+
ac: AC[json['AC']],
|
104
|
+
pr: PR[json['PR']],
|
105
|
+
ui: UI[json['UI']],
|
106
|
+
s: S[json['S']],
|
107
|
+
c: C[json['C']],
|
108
|
+
i: I[json['I']],
|
109
|
+
a: A[json['A']],
|
110
|
+
|
111
|
+
score: json['SCORE']
|
112
|
+
}
|
113
|
+
end
|
114
|
+
|
115
|
+
#
|
116
|
+
# Loads the BM object from the parsed JSON.
|
117
|
+
#
|
118
|
+
# @param [Hash{String => Object}] json
|
119
|
+
# The parsed JSON.
|
120
|
+
#
|
121
|
+
# @return [BM]
|
122
|
+
# The loaded BM object.
|
123
|
+
#
|
124
|
+
def self.load(json)
|
125
|
+
new(**from_json(json))
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
# @return [BM, nil]
|
131
|
+
attr_reader :bm
|
132
|
+
|
133
|
+
class TM
|
134
|
+
|
135
|
+
E = {'X' => :X, 'H' => :H, 'F' => :F, 'P' => :P, 'U' => :U}
|
136
|
+
|
137
|
+
# Exploit Code Maturity.
|
138
|
+
#
|
139
|
+
# @return [:X, :H, :F, :P, :U]
|
140
|
+
attr_reader :e
|
141
|
+
|
142
|
+
RL = {'X' => :X, 'U' => :U, 'W' => :W, 'T' => :T, 'O' => :O}
|
143
|
+
|
144
|
+
# Remediation Level.
|
145
|
+
#
|
146
|
+
# @return [:X, :U, :W, :T, :O]
|
147
|
+
attr_reader :rl
|
148
|
+
|
149
|
+
RC = {'X' => :X, 'C' => :C, 'R' => :R, 'U' => :U}
|
150
|
+
|
151
|
+
# Report Confidence.
|
152
|
+
#
|
153
|
+
# @return [:X, :C, :R, :U]
|
154
|
+
attr_reader :rc
|
155
|
+
|
156
|
+
#
|
157
|
+
# Initializes the TM object.
|
158
|
+
#
|
159
|
+
def initialize(e: nil, rl: nil, rc: nil)
|
160
|
+
@e = e
|
161
|
+
@rl = rl
|
162
|
+
@rc = rc
|
163
|
+
end
|
164
|
+
|
165
|
+
#
|
166
|
+
# Maps the parsed JSON to the Symbol Hash for {#initialize}.
|
167
|
+
#
|
168
|
+
# @param [Hash{String => Object}] json
|
169
|
+
# The parsed JSON.
|
170
|
+
#
|
171
|
+
# @return [Hash{Symbol => Object}]
|
172
|
+
# The mapped Symbol Hash.
|
173
|
+
#
|
174
|
+
def self.from_json(json)
|
175
|
+
{
|
176
|
+
e: E[json['E']],
|
177
|
+
rl: RL[json['RL']],
|
178
|
+
rc: RC[json['RC']]
|
179
|
+
}
|
180
|
+
end
|
181
|
+
|
182
|
+
#
|
183
|
+
# Loads the TM object from the parsed JSON.
|
184
|
+
#
|
185
|
+
# @param [Hash{String => Object}] json
|
186
|
+
# The parsed JSON.
|
187
|
+
#
|
188
|
+
# @return [TM]
|
189
|
+
# The loaded TM object.
|
190
|
+
#
|
191
|
+
def self.load(json)
|
192
|
+
new(**from_json(json))
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
196
|
+
|
197
|
+
# @return [TM, nil]
|
198
|
+
attr_reader :tm
|
199
|
+
|
200
|
+
class EM
|
201
|
+
|
202
|
+
CR = {'X' => :X, 'H' => :H, 'M' => :M, 'L' => :L}
|
203
|
+
|
204
|
+
# Security Requirements Confidentiality.
|
205
|
+
#
|
206
|
+
# @return [:X, :H, :M, :L]
|
207
|
+
attr_reader :cr
|
208
|
+
|
209
|
+
IR = {'X' => :X, 'H' => :H, 'M' => :M, 'L' => :L}
|
210
|
+
|
211
|
+
# Security Requirements Integrity.
|
212
|
+
#
|
213
|
+
# @return [:X, :H, :M, :L]
|
214
|
+
attr_reader :ir
|
215
|
+
|
216
|
+
AR = {'X' => :X, 'H' => :H, 'M' => :M, 'L' => :L}
|
217
|
+
|
218
|
+
# Security Requirements Availability.
|
219
|
+
#
|
220
|
+
# @return [:X, :H, :M, :L]
|
221
|
+
attr_reader :ar
|
222
|
+
|
223
|
+
MAV = {'N' => :N, 'A' => :A, 'L' => :L, 'P' => :P}
|
224
|
+
|
225
|
+
# The Modified Attack Vector.
|
226
|
+
#
|
227
|
+
# @return [:N, :A, :L, :P]
|
228
|
+
attr_reader :mav
|
229
|
+
|
230
|
+
MAC = {'L' => :L, 'H' => :H}
|
231
|
+
|
232
|
+
# The Modified Attack Complexity.
|
233
|
+
#
|
234
|
+
# @return [:L, :H]
|
235
|
+
attr_reader :mac
|
236
|
+
|
237
|
+
MPR = {'N' => :N, 'L' => :L, 'H' => :H}
|
238
|
+
|
239
|
+
# The Modified Privileges Required.
|
240
|
+
#
|
241
|
+
# @return [:N, :L, :H]
|
242
|
+
attr_reader :mpr
|
243
|
+
|
244
|
+
MUI = {'N' => :N, 'R' => :R}
|
245
|
+
|
246
|
+
# The Modified User Interaction.
|
247
|
+
#
|
248
|
+
# @return [:N, :R]
|
249
|
+
attr_reader :mui
|
250
|
+
|
251
|
+
MS = {'U' => :S, 'C' => :C}
|
252
|
+
|
253
|
+
# The Modified Scope.
|
254
|
+
#
|
255
|
+
# @return [:U, :C]
|
256
|
+
attr_reader :ms
|
257
|
+
|
258
|
+
MC = {'H' => :H, 'L' => :L, 'N' => :N}
|
259
|
+
|
260
|
+
# The Modified Confidentiality Impact.
|
261
|
+
#
|
262
|
+
# @return [:H, :L, :N]
|
263
|
+
attr_reader :mc
|
264
|
+
|
265
|
+
MI = {'H' => :H, 'L' => :L, 'N' => :N}
|
266
|
+
|
267
|
+
# The Modified Integrity Impact.
|
268
|
+
#
|
269
|
+
# @return [:H, :L, :N]
|
270
|
+
attr_reader :mi
|
271
|
+
|
272
|
+
MA = {'H' => :H, 'L' => :L, 'N' => :N}
|
273
|
+
|
274
|
+
# The Modified Availability Impact.
|
275
|
+
#
|
276
|
+
# @return [:H, :L, :N]
|
277
|
+
attr_reader :ma
|
278
|
+
|
279
|
+
#
|
280
|
+
# Initializes the EM object.
|
281
|
+
#
|
282
|
+
def initialize(cr: nil, ir: nil, ar: nil, mav: nil, mac: nil,
|
283
|
+
mpr: nil, mui: nil, ms: nil, mc: nil, mi: nil, ma: nil)
|
284
|
+
@cr = cr
|
285
|
+
@ir = ir
|
286
|
+
@ar = ar
|
287
|
+
@mav = mav
|
288
|
+
@mac = mac
|
289
|
+
@mpr = mpr
|
290
|
+
@mui = mui
|
291
|
+
@ms = ms
|
292
|
+
@mc = mc
|
293
|
+
@mi = mi
|
294
|
+
@ma = ma
|
295
|
+
end
|
296
|
+
|
297
|
+
#
|
298
|
+
# Maps the parsed JSON to a Symbol Hash for {#initialize}.
|
299
|
+
#
|
300
|
+
# @param [Hash{String => Object}] json
|
301
|
+
# The parsed JSON.
|
302
|
+
#
|
303
|
+
# @return [Hash{Symbol => Object}]
|
304
|
+
# The mapped Symbol Hash.
|
305
|
+
#
|
306
|
+
def self.from_json(json)
|
307
|
+
{
|
308
|
+
cr: CR[json['CR']],
|
309
|
+
ir: IR[json['IR']],
|
310
|
+
ar: AR[json['AR']],
|
311
|
+
mav: MAV[json['MAV']],
|
312
|
+
mac: MAC[json['MAC']],
|
313
|
+
mpr: MPR[json['MPR']],
|
314
|
+
mui: MUI[json['MUI']],
|
315
|
+
ms: MS[json['MS']],
|
316
|
+
mc: MC[json['MC']],
|
317
|
+
mi: MI[json['MI']],
|
318
|
+
ma: MA[json['MA']]
|
319
|
+
}
|
320
|
+
end
|
321
|
+
|
322
|
+
#
|
323
|
+
# Loads the EM object from the parsed JSON.
|
324
|
+
#
|
325
|
+
# @param [Hash{String => Object}] json
|
326
|
+
# The parsed JSON.
|
327
|
+
#
|
328
|
+
# @return [EM]
|
329
|
+
# The loaded EM object.
|
330
|
+
#
|
331
|
+
def self.load(json)
|
332
|
+
new(**from_json(json))
|
333
|
+
end
|
334
|
+
|
335
|
+
end
|
336
|
+
|
337
|
+
# @return [EM, nil]
|
338
|
+
attr_reader :em
|
339
|
+
|
340
|
+
#
|
341
|
+
# Initializes the CVSSv2.
|
342
|
+
#
|
343
|
+
# @param [BM, nil] bm
|
344
|
+
#
|
345
|
+
# @param [TM, nil] tm
|
346
|
+
#
|
347
|
+
# @param [EM, nil] em
|
348
|
+
#
|
349
|
+
def initialize(bm: nil, tm: nil, em: nil)
|
350
|
+
@bm = bm
|
351
|
+
@tm = tm
|
352
|
+
@em = em
|
353
|
+
end
|
354
|
+
|
355
|
+
#
|
356
|
+
# Maps the parsed JSON to a Symbol Hash for {#initialize}.
|
357
|
+
#
|
358
|
+
# @param [Hash{String => Object}] json
|
359
|
+
# The parsed JSON.
|
360
|
+
#
|
361
|
+
# @return [Hash{Symbol => Object}]
|
362
|
+
# The mapped Symbol Hash.
|
363
|
+
#
|
364
|
+
def self.from_json(json)
|
365
|
+
{
|
366
|
+
bm: json['BM'] && BM.load(json['BM']),
|
367
|
+
tm: json['TM'] && TM.load(json['TM']),
|
368
|
+
em: json['EM'] && EM.load(json['EM'])
|
369
|
+
}
|
370
|
+
end
|
371
|
+
|
372
|
+
#
|
373
|
+
# Loads the CVSSv3 object from the parsed JSON.
|
374
|
+
#
|
375
|
+
# @param [Hash{String => Object}] json
|
376
|
+
# The parsed JSON.
|
377
|
+
#
|
378
|
+
# @return [CVSSv3]
|
379
|
+
# the loaded CVSSv3 object.
|
380
|
+
#
|
381
|
+
def self.load(json)
|
382
|
+
new(**from_json(json))
|
383
|
+
end
|
384
|
+
|
385
|
+
end
|
386
|
+
end
|
387
|
+
end
|
388
|
+
end
|