nvd-json_feeds 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/.document +3 -0
  3. data/.github/workflows/ruby.yml +29 -0
  4. data/.gitignore +9 -0
  5. data/.rspec +1 -0
  6. data/.yardopts +1 -0
  7. data/ChangeLog.md +25 -0
  8. data/Gemfile +13 -0
  9. data/LICENSE.txt +20 -0
  10. data/README.md +136 -0
  11. data/Rakefile +31 -0
  12. data/gemspec.yml +22 -0
  13. data/lib/nvd/json_feeds.rb +25 -0
  14. data/lib/nvd/json_feeds/exceptions.rb +15 -0
  15. data/lib/nvd/json_feeds/feed.rb +50 -0
  16. data/lib/nvd/json_feeds/feed_file.rb +95 -0
  17. data/lib/nvd/json_feeds/feed_uri.rb +131 -0
  18. data/lib/nvd/json_feeds/gz_feed_file.rb +60 -0
  19. data/lib/nvd/json_feeds/gz_feed_uri.rb +25 -0
  20. data/lib/nvd/json_feeds/json_feed_file.rb +21 -0
  21. data/lib/nvd/json_feeds/meta.rb +122 -0
  22. data/lib/nvd/json_feeds/meta_feed_uri.rb +22 -0
  23. data/lib/nvd/json_feeds/schema/configurations.rb +61 -0
  24. data/lib/nvd/json_feeds/schema/configurations/node.rb +98 -0
  25. data/lib/nvd/json_feeds/schema/cpe/has_uri.rb +66 -0
  26. data/lib/nvd/json_feeds/schema/cpe/match.rb +117 -0
  27. data/lib/nvd/json_feeds/schema/cpe/name.rb +67 -0
  28. data/lib/nvd/json_feeds/schema/cve_feed.rb +142 -0
  29. data/lib/nvd/json_feeds/schema/cve_item.rb +94 -0
  30. data/lib/nvd/json_feeds/schema/cvss_v2.rb +298 -0
  31. data/lib/nvd/json_feeds/schema/cvss_v3.rb +332 -0
  32. data/lib/nvd/json_feeds/schema/has_data_version.rb +54 -0
  33. data/lib/nvd/json_feeds/schema/impact.rb +73 -0
  34. data/lib/nvd/json_feeds/schema/impact/base_metric_v2.rb +132 -0
  35. data/lib/nvd/json_feeds/schema/impact/base_metric_v3.rb +79 -0
  36. data/lib/nvd/json_feeds/schema/timestamp.rb +9 -0
  37. data/lib/nvd/json_feeds/version.rb +6 -0
  38. data/lib/nvd/json_feeds/zip_feed_file.rb +64 -0
  39. data/lib/nvd/json_feeds/zip_feed_uri.rb +25 -0
  40. data/nvd-json_feeds.gemspec +61 -0
  41. data/spec/feed_file_examples.rb +27 -0
  42. data/spec/feed_file_spec.rb +42 -0
  43. data/spec/feed_spec.rb +56 -0
  44. data/spec/feed_uri_spec.rb +81 -0
  45. data/spec/fixtures/gz_feed_file/nvdcve-1.1-recent.json.gz +0 -0
  46. data/spec/fixtures/nvdcve-1.1-recent.json +180 -0
  47. data/spec/fixtures/zip_feed_file/nvdcve-1.1-recent.json.zip +0 -0
  48. data/spec/gz_feed_file_spec.rb +66 -0
  49. data/spec/gz_feed_uri_spec.rb +35 -0
  50. data/spec/json_feed_file_spec.rb +18 -0
  51. data/spec/json_feeds_spec.rb +8 -0
  52. data/spec/meta_spec.rb +141 -0
  53. data/spec/schema/configurations/node_spec.rb +87 -0
  54. data/spec/schema/configurations_spec.rb +57 -0
  55. data/spec/schema/cpe/match_spec.rb +188 -0
  56. data/spec/schema/cpe/name_spec.rb +54 -0
  57. data/spec/schema/cve_feed_spec.rb +162 -0
  58. data/spec/schema/cve_item_spec.rb +116 -0
  59. data/spec/schema/impact/base_metric_v2_spec.rb +183 -0
  60. data/spec/schema/impact/base_metric_v3_spec.rb +80 -0
  61. data/spec/schema/impact_spec.rb +53 -0
  62. data/spec/schema/shared_examples.rb +136 -0
  63. data/spec/schema/timestamp_spec.rb +8 -0
  64. data/spec/spec_helper.rb +8 -0
  65. data/spec/zip_feed_file_spec.rb +66 -0
  66. data/spec/zip_feed_uri_spec.rb +35 -0
  67. metadata +156 -0
@@ -0,0 +1,94 @@
1
+ require 'nvd/json_feeds/schema/timestamp'
2
+ require 'nvd/json_feeds/schema/configurations'
3
+ require 'nvd/json_feeds/schema/impact'
4
+ require 'cve_schema/cve'
5
+
6
+ module NVD
7
+ module JSONFeeds
8
+ module Schema
9
+ #
10
+ # Represents the `"CVE_Item"` JSON object.
11
+ #
12
+ class CVEItem
13
+
14
+ # The CVE object.
15
+ #
16
+ # @return [CVESchema::CVE]
17
+ attr_reader :cve
18
+
19
+ # @return [Configurations, nil]
20
+ attr_reader :configurations
21
+
22
+ # @return [Impact, nil]
23
+ attr_reader :impact
24
+
25
+ # @return [DateTime, nil]
26
+ attr_reader :published_date
27
+
28
+ # @return [DateTime, nil]
29
+ attr_reader :last_modified_date
30
+
31
+ #
32
+ # Initializes the CVE Item object.
33
+ #
34
+ # @param [CVESchema::CVE] cve
35
+ # The CVE object.
36
+ #
37
+ def initialize(cve: , configurations: nil,
38
+ impact: nil,
39
+ published_date: nil,
40
+ last_modified_date: nil)
41
+ @cve = cve
42
+
43
+ @configurations = configurations
44
+ @impact = impact
45
+ @published_date = published_date
46
+ @last_modified_date = last_modified_date
47
+ end
48
+
49
+ #
50
+ # Maps the parsed JSON to a Symbol Hash for {#initialize}.
51
+ #
52
+ # @param [Hash{String => Object}] json
53
+ # The parsed JSON.
54
+ #
55
+ # @return [Hash{Symbol => Object}]
56
+ # The mapped Symbol Hash.
57
+ #
58
+ def self.from_json(json)
59
+ {
60
+ cve: CVESchema::CVE.load(json.fetch('cve')),
61
+ configurations: if (configurations = json['configurations'])
62
+ Configurations.load(configurations)
63
+ end,
64
+ impact: if (impact = json['impact'])
65
+ Impact.load(impact)
66
+ end,
67
+
68
+ published_date: if (published_date = json['publishedDate'])
69
+ Timestamp.parse(published_date)
70
+ end,
71
+
72
+ last_modified_date: if (last_modified_date = json['lastModifiedDate'])
73
+ Timestamp.parse(last_modified_date)
74
+ end
75
+ }
76
+ end
77
+
78
+ #
79
+ # Loads the CVE Item object from the parsed JSON.
80
+ #
81
+ # @param [Hash{String => Object}] json
82
+ # The parsed JSON.
83
+ #
84
+ # @return [CVEItem]
85
+ # The loaded CVE Item object.
86
+ #
87
+ def self.load(json)
88
+ new(**from_json(json))
89
+ end
90
+
91
+ end
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,298 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NVD
4
+ module JSONFeeds
5
+ module Schema
6
+ #
7
+ # Represents the `"cvssV2"` value.
8
+ #
9
+ class CVSSv2
10
+
11
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v2.0_beta.json
12
+ VERSIONS = {
13
+ '2.0' => :"2.0"
14
+ }
15
+
16
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v2.0_beta.json
17
+ ACCESS_VECTORS = {
18
+ 'NETWORK' => :NETWORK,
19
+ 'ADJACENT_NETWORK' => :ADJACENT_NETWORK,
20
+ 'LOCAL' => :LOCAL
21
+ }
22
+
23
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v2.0_beta.json
24
+ ACCESS_COMPLEXITIES = {
25
+ 'HIGH' => :HIGH,
26
+ 'MEDIUM' => :MEDIUM,
27
+ 'LOW' => :LOW
28
+ }
29
+
30
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v2.0_beta.json
31
+ AUTHENTICATIONS = {
32
+ 'MULTIPLE' => :MULTIPLE,
33
+ 'SINGLE' => :SINGLE,
34
+ 'NONE' => :NONE
35
+ }
36
+
37
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v2.0_beta.json
38
+ CIAS = {
39
+ 'NONE' => :NONE,
40
+ 'PARTIAL' => :PARTIAL,
41
+ 'COMPLETE' => :COMPLETE
42
+ }
43
+
44
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v2.0_beta.json
45
+ EXPLOITABILITIES = {
46
+ 'UNPROVEN' => :UNPROVEN,
47
+ 'PROOF_OF_CONCEPT' => :PROOF_OF_CONCEPT,
48
+ 'FUNCTIONAL' => :FUNCTIONAL,
49
+ 'HIGH' => :HIGH,
50
+ 'NOT_DEFINED' => :NOT_DEFINED
51
+ }
52
+
53
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v2.0_beta.json
54
+ REMEDIATION_LEVELS = {
55
+ 'OFFICIAL_FIX' => :OFFICIAL_FIX,
56
+ 'TEMPORARY_FIX' => :TEMPORARY_FIX,
57
+ 'WORKAROUND' => :WORKAROUND,
58
+ 'UNAVAILABLE' => :UNAVAILABLE,
59
+ 'NOT_DEFINED' => :NOT_DEFINED
60
+ }
61
+
62
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v2.0_beta.json
63
+ REPORT_CONFIDENCES = {
64
+ 'UNCONFIRMED' => :UNCONFIRMED,
65
+ 'UNCORROBORATED' => :UNCORROBORATED,
66
+ 'CONFIRMED' => :CONFIRMED,
67
+ 'NOT_DEFINED' => :NOT_DEFINED
68
+ }
69
+
70
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v2.0_beta.json
71
+ COLLATERAL_DAMAGE_POTENTIALS = {
72
+ 'NONE' => :NONE,
73
+ 'LOW' => :LOW,
74
+ 'LOW_MEDIUM' => :LOW_MEDIUM,
75
+ 'MEDIUM_HIGH' => :MEDIUM_HIGH,
76
+ 'HIGH' => :HIGH,
77
+ 'NOT_DEFINED' => :NOT_DEFINED
78
+ }
79
+
80
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v2.0_beta.json
81
+ TARGET_DISTRIBUTIONS = {
82
+ "NONE" => :NONE,
83
+ "LOW" => :LOW,
84
+ "MEDIUM" => :MEDIUM,
85
+ "HIGH" => :HIGH,
86
+ "NOT_DEFINED" => :NOT_DEFINED
87
+ }
88
+
89
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v2.0_beta.json
90
+ CIA_REQUIREMENTS = {
91
+ 'LOW' => :LOW,
92
+ 'MEDIUM' => :MEDIUM,
93
+ 'HIGH' => :HIGH,
94
+ 'NOT_DEFINED' => :NOT_DEFINED
95
+ }
96
+
97
+ # @return [:"2.0"]
98
+ attr_reader :version
99
+
100
+ # @return [String]
101
+ attr_reader :vector_string
102
+
103
+ # @return [Float]
104
+ attr_reader :base_score
105
+
106
+ # @return [:NETWORK, :ADJACENT_NETWORK, :LOCAL]]
107
+ attr_reader :access_vector
108
+
109
+ # @return [:HIGH, :MEDIUM, :LOW]
110
+ attr_reader :access_complexity
111
+
112
+ # @return [:MULTIPLE, :SINGLE, :NONE]
113
+ attr_reader :authentication
114
+
115
+ # @return [:NONE, :PARTIAL, :COMPLETE]
116
+ attr_reader :confidentiality_impact
117
+
118
+ # @return [:NONE, :PARTIAL, :COMPLETE]
119
+ attr_reader :integrity_impact
120
+
121
+ # @return [:NONE, :PARTIAL, :COMPLETE]
122
+ attr_reader :availability_impact
123
+
124
+ # @return [Float]
125
+ attr_reader :base_score
126
+
127
+ # @return [:UNPROVEN, :PROOF_OF_CONCEPT, :FUNCTIONAL, :HIGH, :NOT_DEFINED]
128
+ attr_reader :exploitability
129
+
130
+ # @return [:OFFICIAL_FIX, :TEMPORARY_FIX, :WORKAROUND, :UNAVAILABLE, :NOT_DEFINED]
131
+ attr_reader :remediation_level
132
+
133
+ # @return [:UNCONFIRMED, :UNCORROBORATED, :CONFIRMED, :NOT_DEFINED]
134
+ attr_reader :report_confidence
135
+
136
+ # @return [Float, nil]
137
+ attr_reader :temporal_score
138
+
139
+ # @return [:NONE, :LOW, :LOW_MEDIUM, :MEDIUM_HIGH, :HIGH, :NOT_DEFINED]
140
+ attr_reader :collateral_damage_potential
141
+
142
+ # @return [:NONE, :LOW, :MEDIUM, :HIGH, :NOT_DEFINED]
143
+ attr_reader :target_distribution
144
+
145
+ # @return [:NONE, :PARTIAL, :COMPLETE]
146
+ attr_reader :confidentiality_requirement
147
+
148
+ # @return [:NONE, :PARTIAL, :COMPLETE]
149
+ attr_reader :integrity_requirement
150
+
151
+ # @return [:NONE, :PARTIAL, :COMPLETE]
152
+ attr_reader :availability_requirement
153
+
154
+ # @return [Float, nil]
155
+ attr_reader :environmental_score
156
+
157
+ #
158
+ # Initializes the CVSS v2 object.
159
+ #
160
+ def initialize(version: ,
161
+ vector_string: ,
162
+ base_score: ,
163
+ access_vector: nil,
164
+ access_Complexity: nil,
165
+ authentication: nil,
166
+ confidentiality_impact: nil,
167
+ integrity_impact: nil,
168
+ availability_impact: nil,
169
+ exploitability: nil,
170
+ remediation_level: nil,
171
+ report_confidence: nil,
172
+ temporal_score: nil,
173
+ collateral_damage_potential: nil,
174
+ target_distribution: nil,
175
+ confidentiality_requirement: nil,
176
+ integrity_requirement: nil,
177
+ availability_requirement: nil,
178
+ environmental_score: nil)
179
+ @version = version
180
+ @vector_string = vector_string
181
+ @base_score = base_score
182
+
183
+ @access_vector = access_vector
184
+ @access_Complexity = access_Complexity
185
+ @authentication = authentication
186
+ @confidentiality_impact = confidentiality_impact
187
+ @integrity_impact = integrity_impact
188
+ @availability_impact = availability_impact
189
+ @base_score = base_score
190
+ @exploitability = exploitability
191
+ @remediation_level = remediation_level
192
+ @report_confidence = report_confidence
193
+ @temporal_score = temporal_score
194
+ @collateral_damage_potential = collateral_damage_potential
195
+ @target_distribution = target_distribution
196
+ @confidentiality_requirement = confidentiality_requirement
197
+ @integrity_requirement = integrity_requirement
198
+ @availability_requirement = availability_requirement
199
+ @environmental_score = environmental_score
200
+ end
201
+
202
+ #
203
+ # Maps the parsed JSON to a Symbol Hash for {#initialize}.
204
+ #
205
+ # @param [Hash{String => Object}] json
206
+ # The parsed JSON.
207
+ #
208
+ # @return [Hash{Symbol => Object}]
209
+ # The Symbol Hash.
210
+ #
211
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v2.0_beta.json
212
+ #
213
+ def self.from_json(json)
214
+ {
215
+ version: VERSIONS.fetch(json.fetch('version')),
216
+
217
+ vector_string: json.fetch('vectorString'),
218
+
219
+ access_vector: if (value = json['accessVector'])
220
+ ACCESS_VECTORS.fetch(value)
221
+ end,
222
+
223
+ access_Complexity: if (value = json['accessComplexity'])
224
+ ACCESS_COMPLEXITIES.fetch(value)
225
+ end,
226
+
227
+ authentication: if (value = json['authentication'])
228
+ AUTHENTICATIONS.fetch(value)
229
+ end,
230
+
231
+ confidentiality_impact: if (value = json['confidentialityImpact'])
232
+ CIAS.fetch(value)
233
+ end,
234
+
235
+ integrity_impact: if (value = json['integrityImpact'])
236
+ CIAS.fetch(value)
237
+ end,
238
+
239
+ availability_impact: if (value = json['availabilityImpact'])
240
+ CIAS.fetch(value)
241
+ end,
242
+
243
+ base_score: json.fetch('baseScore'),
244
+
245
+ exploitability: if (value = json['exploitability'])
246
+ EXPLOITABILITIES.fetch(value)
247
+ end,
248
+
249
+ remediation_level: if (value = json['remediationLevel'])
250
+ REMEDIATION_LEVELS.fetch(value)
251
+ end,
252
+
253
+ report_confidence: if (value = json['reportConfidence'])
254
+ REPORT_CONFIDENCES.fetch(value)
255
+ end,
256
+
257
+ temporal_score: json['temporalScore'],
258
+
259
+ collateral_damage_potential: if (value = json['collateralDamagePotential'])
260
+ COLLATERAL_DAMAGE_POTENTIALS.fetch(value)
261
+ end,
262
+
263
+ target_distribution: if (value = json['targetDistribution'])
264
+ TARGET_DISTRIBUTIONS.fetch(value)
265
+ end,
266
+
267
+ confidentiality_requirement: if (value = json['confidentialityRequirement'])
268
+ CIA_REQUIREMENTS.fetch(value)
269
+ end,
270
+
271
+ integrity_requirement: if (value = json['integrityRequirement'])
272
+ CIA_REQUIREMENTS.fetch(value)
273
+ end,
274
+
275
+ availability_requirement: if (value = json['availabilityRequirement'])
276
+ CIA_REQUIREMENTS.fetch(value)
277
+ end,
278
+
279
+ environmental_score: json['environmentalScore']
280
+ }
281
+ end
282
+
283
+ #
284
+ # Loads the CVSS v2 object from the parsed JSON.
285
+ #
286
+ # @param [Hash{String => Object}] json
287
+ # The parsed JSON.
288
+ #
289
+ # @return [CVSSv2]
290
+ # The CVSSv3 V2 object.
291
+ #
292
+ def self.load(json)
293
+ new(**from_json(json))
294
+ end
295
+ end
296
+ end
297
+ end
298
+ end
@@ -0,0 +1,332 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NVD
4
+ module JSONFeeds
5
+ module Schema
6
+ #
7
+ # Represents the `"cvssV3"` value.
8
+ #
9
+ class CVSSv3
10
+
11
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v3.x_beta.json
12
+ VERSIONS = {
13
+ '3.0' => :"3.0",
14
+ '3.1' => :"3.1"
15
+ }
16
+
17
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v3.x_beta.json
18
+ ATTACK_VECTORS = {
19
+ 'NETWORK' => :NETWORK,
20
+ 'ADJACENT_NETWORK' => :ADJACENT_NETWORK,
21
+ 'LOCAL' => :LOCAL,
22
+ 'PHYSICAL' => :PHYSICAL
23
+ }
24
+
25
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v3.x_beta.json
26
+ MODIFIED_ATTACK_VECTORS = ATTACK_VECTORS.merge(
27
+ 'NOT_DEFINED' => :NOT_DEFINED
28
+ )
29
+
30
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v3.x_beta.json
31
+ ATTACK_COMPLEXITIES = {
32
+ 'HIGH' => :HIGH,
33
+ 'LOW' => :LOW
34
+ }
35
+
36
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v3.x_beta.json
37
+ MODIFIED_ATTACK_COMPLEXITIES = MODIFIED_ATTACK_VECTORS.merge(
38
+ 'NOT_DEFINED' => :NOT_DEFINED
39
+ )
40
+
41
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v3.x_beta.json
42
+ PRIVILEGES_REQUIRED = {
43
+ 'HIGH' => :HIGH,
44
+ 'LOW' => :LOW,
45
+ 'NONE' => :NONE
46
+ }
47
+
48
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v3.x_beta.json
49
+ MODIFIED_PRIVILEGES_REQUIRED = PRIVILEGES_REQUIRED.merge(
50
+ 'NOT_DEFINED' => :NOT_DEFINED
51
+ )
52
+
53
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v3.x_beta.json
54
+ USER_INTERACTIONS = {
55
+ 'NONE' => :NONE,
56
+ 'REQUIRED' => :REQUIRED
57
+ }
58
+
59
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v3.x_beta.json
60
+ MODIFIED_USER_INTERACTIONS = USER_INTERACTIONS.merge(
61
+ 'NOT_DEFINED' => :NOT_DEFINED
62
+ )
63
+
64
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v3.x_beta.json
65
+ SCOPES = {
66
+ 'UNCHANGED' => :UNCHANGED,
67
+ 'CHANGED' => :CHANGED
68
+ }
69
+
70
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v3.x_beta.json
71
+ MODIFIED_SCOPES = SCOPES.merge(
72
+ 'NOT_DEFINED' => :NOT_DEFINED
73
+ )
74
+
75
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v3.x_beta.json
76
+ CIAS = {
77
+ 'NONE' => :NONE,
78
+ 'LOW' => :LOW,
79
+ 'HIGH' => :HIGH
80
+ }
81
+
82
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v3.x_beta.json
83
+ MODIFIED_CIAS = CIAS.merge(
84
+ 'NOT_DEFINED' => :NOT_DEFINED
85
+ )
86
+
87
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v3.x_beta.json
88
+ EXPLOIT_CODE_MATURITIES = {
89
+ 'UNPROVEN' => :UNPROVEN,
90
+ 'PROOF_OF_CONCEPT' => :PROOF_OF_CONCEPT,
91
+ 'FUNCTIONAL' => :FUNCTIONAL,
92
+ 'HIGH' => :HIGH,
93
+ 'NOT_DEFINED' => :NOT_DEFINED
94
+ }
95
+
96
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v3.x_beta.json
97
+ REMEDIATION_LEVELS = {
98
+ 'OFFICIAL_FIX' => :OFFICIAL_FIX,
99
+ 'TEMPORARY_FIX' => :TEMPORARY_FIX,
100
+ 'WORKAROUND' => :WORKAROUND,
101
+ 'UNAVAILABLE' => :UNAVAILABLE,
102
+ 'NOT_DEFINED' => :NOT_DEFINED
103
+ }
104
+
105
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v3.x_beta.json
106
+ CONFIDENCES = {
107
+ 'UNKNOWN' => :UNKNOWN,
108
+ 'REASONABLE' => :REASONABLE,
109
+ 'CONFIRMED' => :CONFIRMED,
110
+ 'NOT_DEFINED' => :NOT_DEFINED
111
+ }
112
+
113
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v3.x_beta.json
114
+ CIA_REQUIREMENTS = {
115
+ 'LOW' => :LOW,
116
+ 'MEDIUM' => :MEDIUM,
117
+ 'HIGH' => :HIGH,
118
+ 'NOT_DEFINED' => :NOT_DEFINED
119
+ }
120
+
121
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v3.x_beta.json
122
+ SEVERITIES = {
123
+ 'NONE' => :NONE,
124
+ 'LOW' => :LOW,
125
+ 'MEDIUM' => :MEDIUM,
126
+ 'HIGH' => :HIGH,
127
+ 'CRITICAL' => :CRITICAL
128
+ }
129
+
130
+ #
131
+ # Initializes the CVSS v3 object.
132
+ #
133
+ def initialize(version: ,
134
+ vector_string: ,
135
+ base_score: ,
136
+ base_severity: ,
137
+ attack_vector: nil,
138
+ attack_complexity: nil,
139
+ privileges_required: nil,
140
+ user_interaction: nil,
141
+ scope: nil,
142
+ confidentiality_impact: nil,
143
+ integrity_impact: nil,
144
+ availability_impact: nil,
145
+ exploit_code_maturity: nil,
146
+ remediation_level: nil,
147
+ report_confidence: nil,
148
+ temporal_score: nil,
149
+ temporal_severity: nil,
150
+ confidentiality_requirement: nil,
151
+ integrity_requirement: nil,
152
+ availability_requirement: nil,
153
+ modified_attack_vector: nil,
154
+ modified_attack_complexity: nil,
155
+ modified_privileges_required: nil,
156
+ modified_user_interaction: nil,
157
+ modified_scope: nil,
158
+ modified_confidentiality_impact: nil,
159
+ modified_integrity_impact: nil,
160
+ modified_availability_impact: nil,
161
+ environmental_score: nil,
162
+ environmental_severity: nil)
163
+ @version = version
164
+ @vector_string = vector_string
165
+ @base_score = base_score
166
+ @base_severity = base_severity
167
+
168
+ @attack_vector = attack_vector
169
+ @attack_complexity = attack_complexity
170
+ @privileges_required = privileges_required
171
+ @user_interaction = user_interaction
172
+ @scope = scope
173
+ @confidentiality_impact = confidentiality_impact
174
+ @integrity_impact = integrity_impact
175
+ @availability_impact = availability_impact
176
+ @exploit_code_maturity = exploit_code_maturity
177
+ @remediation_level = remediation_level
178
+ @report_confidence = report_confidence
179
+ @temporal_score = temporal_score
180
+ @temporal_severity = temporal_severity
181
+ @confidentiality_requirement = confidentiality_requirement
182
+ @integrity_requirement = integrity_requirement
183
+ @availability_requirement = availability_requirement
184
+ @modified_attack_vector = modified_attack_vector
185
+ @modified_attack_complexity = modified_attack_complexity
186
+ @modified_privileges_required = modified_privileges_required
187
+ @modified_user_interaction = modified_user_interaction
188
+ @modified_scope = modified_scope
189
+ @modified_confidentiality_impact = modified_confidentiality_impact
190
+ @modified_integrity_impact = modified_integrity_impact
191
+ @modified_availability_impact = modified_availability_impact
192
+ @environmental_score = environmental_score
193
+ @environmental_severity = environmental_severity
194
+ end
195
+
196
+ #
197
+ # Maps the parsed JSON to a Symbol Hash for {#initialize}.
198
+ #
199
+ # @param [Hash{String => Object}] json
200
+ # The parsed JSON.
201
+ #
202
+ # @return [Hash{Symbol => Object}]
203
+ # The Symbol Hash.
204
+ #
205
+ # @see https://csrc.nist.gov/schema/nvd/feed/1.1-Beta/cvss-v3.x_beta.json
206
+ #
207
+ def self.from_json(json)
208
+ {
209
+ version: VERSIONS.fetch(json.fetch('version')),
210
+ vector_string: json.fetch('vectorString'),
211
+
212
+ attack_vector: if (value = json['attackVector'])
213
+ ATTACK_VECTORS.fetch(value)
214
+ end,
215
+
216
+ attack_complexity: if (value = json['attackComplexity'])
217
+ ATTACK_COMPLEXITIES.fetch(value)
218
+ end,
219
+
220
+ privileges_required: if (value = json['privilegesRequired'])
221
+ PRIVILEGES_REQUIRED.fetch(value)
222
+ end,
223
+
224
+ user_interaction: if (value = json['userInteraction'])
225
+ USER_INTERACTIONS.fetch(value)
226
+ end,
227
+
228
+ scope: if (value = json['scope'])
229
+ SCOPES.fetch(value)
230
+ end,
231
+
232
+ confidentiality_impact: if (value = json['confidentialityImpact'])
233
+ CIAS.fetch(value)
234
+ end,
235
+
236
+ integrity_impact: if (value = json['integrityImpact'])
237
+ CIAS.fetch(value)
238
+ end,
239
+
240
+ availability_impact: if (value = json['availabilityImpact'])
241
+ CIAS.fetch(value)
242
+ end,
243
+
244
+ base_score: json['baseScore'],
245
+ base_severity: if (value = json['baseSeverity'])
246
+ SEVERITIES.fetch(value)
247
+ end,
248
+
249
+ exploit_code_maturity: if (value = json['exploitCodeMaturity'])
250
+ EXPLOIT_CODE_MATURITIES.fetch(value)
251
+ end,
252
+
253
+ remediation_level: if (value = json['remediationLevel'])
254
+ REMEDIATION_LEVELS.fetch(value)
255
+ end,
256
+
257
+ report_confidence: if (value = json['reportConfidence'])
258
+ CONFIDENCES.fetch(value)
259
+ end,
260
+
261
+ temporal_score: json['temporalScore'],
262
+
263
+ temporal_severity: if (value = json['temporalSeverity'])
264
+ SEVERITIES.fetch(value)
265
+ end,
266
+
267
+ confidentiality_requirement: if (value = json['confidentialityRequirement'])
268
+ CIA_REQUIREMENTS.fetch(value)
269
+ end,
270
+
271
+ integrity_requirement: if (value = json['integrityRequirement'])
272
+ CIA_REQUIREMENTS.fetch(value)
273
+ end,
274
+
275
+ availability_requirement: if (value = json['availabilityRequirement'])
276
+ CIA_REQUIREMENTS.fetch(value)
277
+ end,
278
+
279
+ modified_attack_vector: if (value = json['modifiedAttackVector'])
280
+ MODIFIED_ATTACK_VECTORS.fetch(value)
281
+ end,
282
+
283
+ modified_attack_complexity: if (value = json['modifiedAttackComplexity'])
284
+ MODIFIED_ATTACK_COMPLEXITIES.fetch(value)
285
+ end,
286
+
287
+ modified_privileges_required: if (value = json['modifiedPrivilegesRequired'])
288
+ MODIFIED_PRIVILEGES_REQUIRED.fetch(value)
289
+ end,
290
+
291
+ modified_user_interaction: if (value = json['modifiedUserInteraction'])
292
+ MODIFIED_USER_INTERACTIONS.fetch(value)
293
+ end,
294
+
295
+ modified_scope: if (value = json['modifiedScope'])
296
+ SCOPES.fetch(value)
297
+ end,
298
+
299
+ modified_confidentiality_impact: if (value = json['modifiedConfidentialityImpact'])
300
+ MODIFIED_CIA.fetch(value)
301
+ end,
302
+
303
+ modified_integrity_impact: if (value = json['modifiedIntegrityImpact'])
304
+ MODIFIED_CIA.fetch(value)
305
+ end,
306
+
307
+ modified_availability_impact: if (value = json['modifiedAvailabilityImpact'])
308
+ MODIFIED_CIA.fetch(value)
309
+ end,
310
+
311
+ environmental_score: json['environmentalScore'],
312
+ environmental_severity: json['environmentalSeverity']
313
+ }
314
+ end
315
+
316
+ #
317
+ # Loads the CVSS v3 object from the parsed JSON.
318
+ #
319
+ # @param [Hash{String => Object}] json
320
+ # The parsed JSON.
321
+ #
322
+ # @return [CVSSv3]
323
+ # The CVSSv3 V3 object.
324
+ #
325
+ def self.load(json)
326
+ new(**from_json(json))
327
+ end
328
+
329
+ end
330
+ end
331
+ end
332
+ end