nvd-json_feeds 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.
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,54 @@
1
+ require 'spec_helper'
2
+ require 'schema/shared_examples'
3
+ require 'nvd/json_feeds/schema/cpe/name'
4
+
5
+ describe Schema::CPE::Name do
6
+ describe "#initialize" do
7
+ context "when cpe23uri: is given" do
8
+ let(:cpe23uri) { 'cpe:2.3:a:bitcoinsv:bitcoin_sv:*:*:*:*:*:*:*:*' }
9
+
10
+ subject { described_class.new(cpe23uri: cpe23uri) }
11
+
12
+ it "must set #cpe23uri" do
13
+ expect(subject.cpe23uri).to eq(cpe23uri)
14
+ end
15
+
16
+ context "and when last_modified_date: is given" do
17
+ let(:last_modified_date) { DateTime.now }
18
+
19
+ subject do
20
+ described_class.new(
21
+ cpe23uri: cpe23uri,
22
+ last_modified_date: last_modified_date
23
+ )
24
+ end
25
+
26
+ it "must set #last_modified_date" do
27
+ expect(subject.last_modified_date).to eq(last_modified_date)
28
+ end
29
+ end
30
+
31
+ context "but when last_modified_date: is not given" do
32
+ it { expect(subject.last_modified_date).to be(nil) }
33
+ end
34
+ end
35
+
36
+ context "but when cpe23uri: is not given" do
37
+ it do
38
+ expect {
39
+ described_class.new
40
+ }.to raise_error(ArgumentError)
41
+ end
42
+ end
43
+ end
44
+
45
+ describe ".load" do
46
+ pending 'need to find an example containing the "cpe_name" key' do
47
+ include_examples ".load"
48
+
49
+ let(:json_node) do
50
+ json_tree['CVE_Items'][0]['configurations']['nodes'][0]['cpe_match'][0]['cpe_name']
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,162 @@
1
+ require 'spec_helper'
2
+ require 'schema/shared_examples'
3
+ require 'nvd/json_feeds/schema/cve_feed'
4
+
5
+ describe NVD::JSONFeeds::Schema::CVEFeed do
6
+ describe "#initialize" do
7
+ let(:data_version) { :"4.0" }
8
+ let(:data_type) { :CVE }
9
+ let(:data_format) { :MITRE }
10
+ let(:cve_items) { [double(:CVEItem1), double(:CVEItem2)] }
11
+
12
+ subject do
13
+ described_class.new(
14
+ data_version: data_version,
15
+ data_type: data_type,
16
+ data_format: data_format,
17
+ cve_items: cve_items
18
+ )
19
+ end
20
+
21
+ it "must set #data_version" do
22
+ expect(subject.data_version).to eq(data_version)
23
+ end
24
+
25
+ it "must set #data_type" do
26
+ expect(subject.data_type).to eq(data_type)
27
+ end
28
+
29
+ it "must set #data_format" do
30
+ expect(subject.data_format).to eq(data_format)
31
+ end
32
+
33
+ it "must set #cve_items" do
34
+ expect(subject.cve_items).to eq(cve_items)
35
+ end
36
+
37
+ context "and when data_number_of_cves: is given" do
38
+ let(:data_number_of_cves) { 2 }
39
+
40
+ subject do
41
+ described_class.new(
42
+ data_version: data_version,
43
+ data_type: data_type,
44
+ data_format: data_format,
45
+ data_number_of_cves: data_number_of_cves,
46
+ cve_items: cve_items
47
+ )
48
+ end
49
+
50
+ it "must set #data_number_of_cves" do
51
+ expect(subject.data_number_of_cves).to eq(data_number_of_cves)
52
+ end
53
+ end
54
+
55
+ context "but when data_number_of_cves: is not given" do
56
+ it { expect(subject.data_number_of_cves).to be(nil) }
57
+ end
58
+
59
+ context "and when data_timestamp: is given" do
60
+ let(:data_timestamp) { DateTime.now }
61
+
62
+ subject do
63
+ described_class.new(
64
+ data_version: data_version,
65
+ data_type: data_type,
66
+ data_format: data_format,
67
+ data_timestamp: data_timestamp,
68
+ cve_items: cve_items
69
+ )
70
+ end
71
+
72
+ it "must set #data_timestamp" do
73
+ expect(subject.data_timestamp).to eq(data_timestamp)
74
+ end
75
+ end
76
+
77
+ context "but when data_timestamp: is not given" do
78
+ it { expect(subject.data_timestamp).to be(nil) }
79
+ end
80
+
81
+ context "but when data_version: is not given" do
82
+ it do
83
+ expect {
84
+ described_class.new(
85
+ data_type: data_type,
86
+ data_format: data_format,
87
+ cve_items: cve_items
88
+ )
89
+ }.to raise_error(ArgumentError)
90
+ end
91
+ end
92
+
93
+ context "but when data_type: is not given" do
94
+ it do
95
+ expect {
96
+ described_class.new(
97
+ data_version: data_version,
98
+ data_format: data_format,
99
+ cve_items: cve_items
100
+ )
101
+ }.to raise_error(ArgumentError)
102
+ end
103
+ end
104
+
105
+ context "but when data_format: is not given" do
106
+ it do
107
+ expect {
108
+ described_class.new(
109
+ data_version: data_version,
110
+ data_type: data_type,
111
+ cve_items: cve_items
112
+ )
113
+ }.to raise_error(ArgumentError)
114
+ end
115
+ end
116
+
117
+ context "but when cve_items: is not given" do
118
+ it do
119
+ expect {
120
+ described_class.new(
121
+ data_version: data_version,
122
+ data_type: data_type,
123
+ data_format: data_format
124
+ )
125
+ }.to raise_error(ArgumentError)
126
+ end
127
+ end
128
+ end
129
+
130
+ describe ".load" do
131
+ include_examples ".load"
132
+
133
+ include_examples "JSON field", json_key: 'CVE_data_type',
134
+ required: true,
135
+ method: :data_type,
136
+ map: described_class::DATA_TYPES
137
+
138
+ include_examples "JSON field", json_key: 'CVE_data_format',
139
+ required: true,
140
+ method: :data_format,
141
+ map: described_class::DATA_FORMATS
142
+
143
+ include_examples "JSON field", json_key: 'CVE_data_version',
144
+ required: true,
145
+ method: :data_version,
146
+ map: described_class::DATA_VERSIONS
147
+
148
+ include_examples "JSON field", json_key: 'CVE_data_numberOfCVEs',
149
+ required: true,
150
+ method: :data_number_of_cves,
151
+ value: ->{ json_value.to_i }
152
+
153
+ include_examples "JSON field", json_key: 'CVE_data_timestamp',
154
+ method: :data_timestamp,
155
+ value: ->{ Schema::Timestamp.parse(json_value) }
156
+
157
+ include_examples "JSON Array field", json_key: 'CVE_Items',
158
+ method: :cve_items,
159
+ required: true,
160
+ element_class: Schema::CVEItem
161
+ end
162
+ end
@@ -0,0 +1,116 @@
1
+ require 'spec_helper'
2
+ require 'schema/shared_examples'
3
+ require 'nvd/json_feeds/schema/cve_item'
4
+
5
+ describe NVD::JSONFeeds::Schema::CVEItem do
6
+ describe "#initialize" do
7
+ context "when cve: is given" do
8
+ let(:cve) { double("CVESchema::CVE") }
9
+
10
+ subject { described_class.new(cve: cve) }
11
+
12
+ it "must set #cve" do
13
+ expect(subject.cve).to eq(cve)
14
+ end
15
+
16
+ context "and when configurations: is given" do
17
+ let(:configurations) { double(:Configurations) }
18
+
19
+ subject do
20
+ described_class.new(cve: cve, configurations: configurations)
21
+ end
22
+
23
+ it "must set #configurations" do
24
+ expect(subject.configurations).to eq(configurations)
25
+ end
26
+ end
27
+
28
+ context "and when configurations: is not given" do
29
+ it { expect(subject.configurations).to be(nil) }
30
+ end
31
+
32
+ context "and when impact: is given" do
33
+ let(:impact) { double(:Impact) }
34
+
35
+ subject do
36
+ described_class.new(cve: cve, impact: impact)
37
+ end
38
+
39
+ it "must set #impact" do
40
+ expect(subject.impact).to eq(impact)
41
+ end
42
+ end
43
+
44
+ context "and when impact: is not given" do
45
+ it { expect(subject.impact).to be(nil) }
46
+ end
47
+
48
+ context "and when published_date: is given" do
49
+ let(:published_date) { double(:published_date) }
50
+
51
+ subject do
52
+ described_class.new(cve: cve, published_date: published_date)
53
+ end
54
+
55
+ it "must set #published_date" do
56
+ expect(subject.published_date).to eq(published_date)
57
+ end
58
+ end
59
+
60
+ context "and when published_date: is not given" do
61
+ it { expect(subject.published_date).to be(nil) }
62
+ end
63
+
64
+ context "and when last_modified_date: is given" do
65
+ let(:last_modified_date) { double(:last_modified_date) }
66
+
67
+ subject do
68
+ described_class.new(cve: cve, last_modified_date: last_modified_date)
69
+ end
70
+
71
+ it "must set #last_modified_date" do
72
+ expect(subject.last_modified_date).to eq(last_modified_date)
73
+ end
74
+ end
75
+
76
+ context "and when last_modified_date: is not given" do
77
+ it { expect(subject.last_modified_date).to be(nil) }
78
+ end
79
+ end
80
+
81
+ context "when cve: is not given" do
82
+ it do
83
+ expect {
84
+ described_class.new
85
+ }.to raise_error(ArgumentError)
86
+ end
87
+ end
88
+ end
89
+
90
+ describe ".load" do
91
+ include_examples ".load"
92
+
93
+ let(:json_node) { json_tree['CVE_Items'][0] }
94
+
95
+ include_examples "JSON Object field", json_key: 'cve',
96
+ required: true,
97
+ method: :cve,
98
+ object_class: CVESchema::CVE
99
+
100
+ include_examples "JSON Object field", json_key: 'configurations',
101
+ method: :configurations,
102
+ object_class: Schema::Configurations
103
+
104
+ include_examples "JSON Object field", json_key: 'impact',
105
+ method: :impact,
106
+ object_class: Schema::Impact
107
+
108
+ include_examples "JSON field", json_key: 'publishedDate',
109
+ method: :published_date,
110
+ value: ->{ Schema::Timestamp.parse(json_value) }
111
+
112
+ include_examples "JSON field", json_key: 'lastModifiedDate',
113
+ method: :last_modified_date,
114
+ value: ->{ Schema::Timestamp.parse(json_value) }
115
+ end
116
+ end
@@ -0,0 +1,183 @@
1
+ require 'spec_helper'
2
+ require 'schema/shared_examples'
3
+ require 'nvd/json_feeds/schema/impact/base_metric_v2'
4
+
5
+ describe Schema::Impact::BaseMetricV2 do
6
+ describe "#initialize" do
7
+ context "when cvss_v2: is given" do
8
+ let(:cvss_v2) { double(:CVSSv3) }
9
+
10
+ subject { described_class.new(cvss_v2: cvss_v2) }
11
+
12
+ it "must set #cvss_v2" do
13
+ expect(subject.cvss_v2).to eq(cvss_v2)
14
+ end
15
+ end
16
+
17
+ context "when cvss_v2: is not given" do
18
+ it { expect(subject.cvss_v2).to be(nil) }
19
+ end
20
+
21
+ context "when severity: is given" do
22
+ let(:severity) { 'high' }
23
+
24
+ subject do
25
+ described_class.new(severity: severity)
26
+ end
27
+
28
+ it "must set #severity" do
29
+ expect(subject.severity).to eq(severity)
30
+ end
31
+ end
32
+
33
+ context "when severity: is not given" do
34
+ it { expect(subject.severity).to be(nil) }
35
+ end
36
+
37
+ context "when exploitability_score: is given" do
38
+ let(:exploitability_score) { 5.0 }
39
+
40
+ subject do
41
+ described_class.new(exploitability_score: exploitability_score)
42
+ end
43
+
44
+ it "must set #exploitability_score" do
45
+ expect(subject.exploitability_score).to eq(exploitability_score)
46
+ end
47
+ end
48
+
49
+ context "when exploitability_score: is not given" do
50
+ it { expect(subject.exploitability_score).to be(nil) }
51
+ end
52
+
53
+ context "when impact_score: is given" do
54
+ let(:impact_score) { 5.0 }
55
+
56
+ subject do
57
+ described_class.new(impact_score: impact_score)
58
+ end
59
+
60
+ it "must set #impact_score" do
61
+ expect(subject.impact_score).to eq(impact_score)
62
+ end
63
+ end
64
+
65
+ context "when impact_score: is not given" do
66
+ it { expect(subject.impact_score).to be(nil) }
67
+ end
68
+
69
+ context "when ac_insuf_info: is given" do
70
+ let(:ac_insuf_info) { 'high' }
71
+
72
+ subject do
73
+ described_class.new(ac_insuf_info: ac_insuf_info)
74
+ end
75
+
76
+ it "must set #ac_insuf_info" do
77
+ expect(subject.ac_insuf_info).to eq(ac_insuf_info)
78
+ end
79
+ end
80
+
81
+ context "when ac_insuf_info: is not given" do
82
+ it { expect(subject.ac_insuf_info).to be(nil) }
83
+ end
84
+
85
+ context "when obtain_all_privilege: is given" do
86
+ let(:obtain_all_privilege) { 'high' }
87
+
88
+ subject do
89
+ described_class.new(obtain_all_privilege: obtain_all_privilege)
90
+ end
91
+
92
+ it "must set #obtain_all_privileges" do
93
+ expect(subject.obtain_all_privilege).to eq(obtain_all_privilege)
94
+ end
95
+ end
96
+
97
+ context "when obtain_all_privilege: is not given" do
98
+ it { expect(subject.obtain_all_privilege).to be(nil) }
99
+ end
100
+
101
+ context "when obtain_user_privilege: is given" do
102
+ let(:obtain_user_privilege) { 'high' }
103
+
104
+ subject do
105
+ described_class.new(obtain_user_privilege: obtain_user_privilege)
106
+ end
107
+
108
+ it "must set #obtain_user_privilege" do
109
+ expect(subject.obtain_user_privilege).to eq(obtain_user_privilege)
110
+ end
111
+ end
112
+
113
+ context "when obtain_user_privilege: is not given" do
114
+ it { expect(subject.obtain_user_privilege).to be(nil) }
115
+ end
116
+
117
+ context "when obtain_other_privilege: is given" do
118
+ let(:obtain_other_privilege) { 'high' }
119
+
120
+ subject do
121
+ described_class.new(obtain_other_privilege: obtain_other_privilege)
122
+ end
123
+
124
+ it "must set #obtain_other_privilege" do
125
+ expect(subject.obtain_other_privilege).to eq(obtain_other_privilege)
126
+ end
127
+ end
128
+
129
+ context "when obtain_other_privilege: is not given" do
130
+ it { expect(subject.obtain_other_privilege).to be(nil) }
131
+ end
132
+
133
+ context "when user_interaction_required: is given" do
134
+ let(:user_interaction_required) { 'high' }
135
+
136
+ subject do
137
+ described_class.new(user_interaction_required: user_interaction_required)
138
+ end
139
+
140
+ it "must set #user_interaction_required" do
141
+ expect(subject.user_interaction_required).to eq(user_interaction_required)
142
+ end
143
+ end
144
+
145
+ context "when user_interaction_required: is not given" do
146
+ it { expect(subject.user_interaction_required).to be(nil) }
147
+ end
148
+ end
149
+
150
+ describe ".load" do
151
+ include_examples ".load"
152
+
153
+ let(:json_node) { json_tree['CVE_Items'][0]['impact']['baseMetricV2'] }
154
+
155
+ include_examples "JSON Object field", json_key: 'cvssV2',
156
+ method: :cvss_v2,
157
+ object_class: Schema::CVSSv2
158
+
159
+ include_examples "JSON field", json_key: 'severity',
160
+ method: :severity
161
+
162
+ include_examples "JSON field", json_key: 'exploitabilityScore',
163
+ method: :exploitability_score
164
+
165
+ include_examples "JSON field", json_key: 'impactScore',
166
+ method: :impact_score
167
+
168
+ include_examples "JSON field", json_key: 'acInsufInfo',
169
+ method: :ac_insuf_info
170
+
171
+ include_examples "JSON field", json_key: 'obtainAllPrivilege',
172
+ method: :obtain_all_privilege
173
+
174
+ include_examples "JSON field", json_key: 'obtainUserPrivilege',
175
+ method: :obtain_user_privilege
176
+
177
+ include_examples "JSON field", json_key: 'obtainOtherPrivilege',
178
+ method: :obtain_other_privilege
179
+
180
+ include_examples "JSON field", json_key: 'userInteractionRequired',
181
+ method: :user_interaction_required
182
+ end
183
+ end