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