yavdb 0.4.4 → 0.4.5

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9f0547b87d256354a1353e774f878fe8f750e6c2
4
- data.tar.gz: cb90e74feaea0a417dc28e28471bfd8be630fff6
3
+ metadata.gz: a18c36ce6f55c809ffc97c80f55090ae228aac37
4
+ data.tar.gz: 54780f521f02012b41710ce2d960295ef6ebaefa
5
5
  SHA512:
6
- metadata.gz: 184b6626614ccde3b38cc486414ec98303aae946476acc4b98f624bec026ed96b8c651afc29b833f31625e1b7a5f7b41180f759f58a8cac1d498c194101e0055
7
- data.tar.gz: 98cc1793d053550d58f90807a76a66197d9da2432308cf8ada6326bb84bd83d82e08bd00dd30e6f73b3c7759da2d263867a43375397b616392ee6b381763d84c
6
+ metadata.gz: 15a22f778a8a03760996abd841cfdf63736985fec74ee670fc2737a39930539c2dbda06ce13fe222ad39263dfe18a7f0885fb3ad69b1d154f9773bc027533c54
7
+ data.tar.gz: 85f4cfe790a5c2a39967fda83d8b2f414c060ee96153edf4c3b18e63b40861b0b851176e084940decdd879a998d38af3d74aa0c83c95abd66ff53f8ba03bf8e0
data/Gemfile.lock CHANGED
@@ -1,11 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- yavdb (0.4.4)
4
+ yavdb (0.4.5)
5
+ execjs (~> 2.7.0)
5
6
  json (~> 2.1)
6
7
  kramdown (~> 1.17)
7
8
  oga (~> 2.15)
8
9
  semantic_interval (~> 0.1)
10
+ therubyracer (~> 0.12)
9
11
  thor (~> 0.20)
10
12
 
11
13
  GEM
@@ -17,9 +19,11 @@ GEM
17
19
  simplecov
18
20
  diff-lcs (1.3)
19
21
  docile (1.3.1)
22
+ execjs (2.7.0)
20
23
  jaro_winkler (1.5.1)
21
24
  json (2.1.0)
22
25
  kramdown (1.17.0)
26
+ libv8 (3.16.14.19)
23
27
  oga (2.15)
24
28
  ast
25
29
  ruby-ll (~> 2.1)
@@ -29,6 +33,7 @@ GEM
29
33
  powerpack (0.1.2)
30
34
  rainbow (3.0.0)
31
35
  rake (12.3.1)
36
+ ref (2.0.0)
32
37
  rspec (3.8.0)
33
38
  rspec-core (~> 3.8.0)
34
39
  rspec-expectations (~> 3.8.0)
@@ -64,7 +69,10 @@ GEM
64
69
  json (>= 1.8, < 3)
65
70
  simplecov-html (~> 0.10.0)
66
71
  simplecov-html (0.10.2)
67
- thor (0.20.0)
72
+ therubyracer (0.12.3)
73
+ libv8 (~> 3.16.14.15)
74
+ ref
75
+ thor (0.20.3)
68
76
  unicode-display_width (1.4.0)
69
77
 
70
78
  PLATFORMS
@@ -82,4 +90,4 @@ DEPENDENCIES
82
90
  yavdb!
83
91
 
84
92
  BUNDLED WITH
85
- 1.16.6
93
+ 1.17.1
data/README.md CHANGED
@@ -13,7 +13,6 @@ The sources for this database include
13
13
  [Rubysec](https://rubysec.com/),
14
14
  [snyk](https://snyk.io/),
15
15
  [OSSIndex (deprecated)](https://ossindex.net/),
16
- [NodeSecurity (deprecated)](https://nodesecurity.io/),
17
16
  [Friends of PHP](https://github.com/FriendsOfPHP/security-advisories),
18
17
  [Magento Related Security Advisories](https://github.com/victims/victims-cve-db),
19
18
  [Victims CVE Database](https://github.com/victims/victims-cve-db)
@@ -39,7 +39,7 @@ module YAVDB
39
39
  file_paths.map do |file_path|
40
40
  advisory_hash = YAML.load_file(file_path)
41
41
  url = "#{repository_url}/blob/master/#{file_path}"
42
- filename = File.basename(file_path, '.yml')
42
+ filename = File.basename(file_path, '.yaml')
43
43
  create(url, filename, advisory_hash)
44
44
  end
45
45
  end
@@ -59,8 +59,7 @@ module YAVDB
59
59
 
60
60
  package_name = advisory_hash['reference'].gsub(%r{composer:\/\/(.*)}, '\1')
61
61
 
62
- vuln_id_stamp = (cves && cves[0]) || filename
63
- vuln_id = "friendsofphp:packagist:#{package_name}:#{vuln_id_stamp}"
62
+ vuln_id = "friendsofphp:packagist:#{package_name}:#{filename}"
64
63
 
65
64
  YAVDB::Advisory.new(
66
65
  vuln_id,
@@ -0,0 +1,129 @@
1
+ # yavdb - The Free and Open Source vulnerability database
2
+ # Copyright (C) 2017-present Rodrigo Fernandes
3
+ #
4
+ # This program is free software: you can redistribute it and/or modify
5
+ # it under the terms of the GNU Affero General Public License as
6
+ # published by the Free Software Foundation, either version 3 of the
7
+ # License, or (at your option) any later version.
8
+ #
9
+ # This program is distributed in the hope that it will be useful,
10
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ # GNU Affero General Public License for more details.
13
+ #
14
+ # You should have received a copy of the GNU Affero General Public License
15
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
16
+
17
+ require 'execjs'
18
+ require 'oga'
19
+ require 'oga/xml/entities'
20
+
21
+ require_relative '../dtos/advisory'
22
+ require_relative '../utils/http'
23
+
24
+ module YAVDB
25
+ module Sources
26
+ module NPMJS
27
+ class Client
28
+
29
+ API_URL = 'https://www.npmjs.com'
30
+
31
+ def self.advisories
32
+ packages = fetch_packages_recursive(0)
33
+ parse_vulnerabilities(packages)
34
+ end
35
+
36
+ class << self
37
+
38
+ private
39
+
40
+ def fetch_packages_recursive(page_number)
41
+ page = get_page_html(get_page_url(page_number), false, 'npmjs/feed')
42
+
43
+ script_tag = page.css('script').find { |script| script.text.include?('window.__context__') }.text
44
+ context = ExecJS.compile("var window = {};\n#{script_tag.force_encoding('utf-8')};")
45
+ advisory_data = context.exec('return window.__context__.context.advisoriesData')
46
+
47
+ packages = advisory_data['objects']
48
+
49
+ next_url = advisory_data['urls']['next']
50
+ next_packages = if next_url && !next_url&.include?("page=#{page_number}")
51
+ fetch_packages_recursive(page_number + 1)
52
+ else
53
+ []
54
+ end
55
+
56
+ packages.concat(next_packages)
57
+ end
58
+
59
+ def parse_vulnerabilities(packages)
60
+ packages.map { |package| create(package) }.flatten
61
+ end
62
+
63
+ def create(package)
64
+ published_date = Date.strptime(package['created'], '%s')
65
+ updated_date = Date.strptime(package['updated'], '%s')
66
+
67
+ cves = package['cves'] || []
68
+
69
+ versions = [package['vulnerable_versions']]
70
+ versions = ['*'] unless versions.any?
71
+
72
+ vuln_id = "npmjs:npm:#{package['module_name']}:#{package['id']}"
73
+
74
+ YAVDB::Advisory.new(
75
+ vuln_id,
76
+ package['title'],
77
+ package['overview'],
78
+ package['module_name'],
79
+ versions,
80
+ nil, #:unaffected_versions
81
+ nil, #:patched_versions
82
+ parse_severity(package['severity']),
83
+ 'npm',
84
+ cves,
85
+ package['cwe'],
86
+ nil, #:osvdb
87
+ nil, #:cvss_v2_vector
88
+ nil, #:cvss_v2_score
89
+ nil, #:cvss_v3_vector
90
+ nil, #:cvss_v3_score
91
+ published_date,
92
+ published_date,
93
+ updated_date,
94
+ package['found_by']['name'],
95
+ package['url'],
96
+ package['url']
97
+ )
98
+ end
99
+
100
+ def get_page_html(source_url, with_cache, group_cache_key)
101
+ body_lines = YAVDB::Utils::HTTP.get_page_contents(source_url, with_cache, group_cache_key)
102
+ Oga.parse_html(body_lines, :strict => true)
103
+ end
104
+
105
+ def get_page_url(page)
106
+ "#{API_URL}/advisories?page=#{page}&perPage=300&order=-id"
107
+ end
108
+
109
+ def parse_severity(severity)
110
+ case severity
111
+ when 'low' then
112
+ 'low'
113
+ when 'moderate' then
114
+ 'medium'
115
+ when 'high' then
116
+ 'high'
117
+ when 'critical' then
118
+ 'high'
119
+ else
120
+ 'high'
121
+ end
122
+ end
123
+
124
+ end
125
+
126
+ end
127
+ end
128
+ end
129
+ end
@@ -96,8 +96,7 @@ module YAVDB
96
96
  .map { |version| version.gsub("''", '') }
97
97
  versions = ['*'] unless versions.any?
98
98
 
99
- vuln_id_stamp = (cve && cve[0]) || published_date
100
- vuln_id = "ossindex:#{package_manager}:#{package_name}:#{vuln_id_stamp}"
99
+ vuln_id = "ossindex:#{package_manager}:#{package_name}:#{advisory['id']}"
101
100
 
102
101
  YAVDB::Advisory.new(
103
102
  vuln_id,
@@ -43,20 +43,19 @@ module YAVDB
43
43
 
44
44
  private
45
45
 
46
- def create(_file_path, advisory_hash)
46
+ def create(file_path, advisory_hash)
47
47
  date = Date.strptime(advisory_hash['date'].to_s, '%Y-%m-%d')
48
48
  severity = severity(advisory_hash['cvss_v2'], advisory_hash['cvss_v3'])
49
49
  cve = advisory_hash['cve'] && "CVE-#{advisory_hash['cve']}"
50
- osvdb = advisory_hash['osvdb'] && "OSVDB-#{advisory_hash['osvdb']}"
51
50
  references = references(advisory_hash)
51
+ filename = File.basename(file_path, '.yml')
52
52
  vulnerable_versions = if advisory_hash['unaffected_versions'] || advisory_hash['patched_versions']
53
53
  nil
54
54
  else
55
55
  ['*']
56
56
  end
57
57
 
58
- vuln_id_stamp = cve || osvdb || date
59
- vuln_id = "rubyadvisory:rubygems:#{advisory_hash['gem']}:#{vuln_id_stamp}"
58
+ vuln_id = "rubyadvisory:rubygems:#{advisory_hash['gem']}:#{filename}"
60
59
 
61
60
  YAVDB::Advisory.new(
62
61
  vuln_id,
@@ -119,9 +119,7 @@ module YAVDB
119
119
  published_date
120
120
  end
121
121
 
122
- vuln_id_stamp = (sidebar_data[:cve] && sidebar_data[:cve][0]) ||
123
- sidebar_data[:id].split(%r{-|:}).last ||
124
- disclosed_date
122
+ vuln_id_stamp = sidebar_data[:id].split(%r{-|:}).last || disclosed_date
125
123
  vuln_id = "snykio:#{package_manager}:#{affected_package}:#{vuln_id_stamp}"
126
124
 
127
125
  YAVDB::Advisory.new(
@@ -47,6 +47,8 @@ module YAVDB
47
47
  case response
48
48
  when Net::HTTPNotFound then
49
49
  raise ArgumentError, 'page not found'
50
+ when Net::HTTPTooManyRequests then
51
+ raise ArgumentError, 'too many requests'
50
52
  else
51
53
  response.body.lines
52
54
  end
data/lib/yavdb/version.rb CHANGED
@@ -16,6 +16,6 @@
16
16
 
17
17
  module YAVDB
18
18
 
19
- VERSION = '0.4.4'
19
+ VERSION = '0.4.5'
20
20
 
21
21
  end
data/yavdb.gemspec CHANGED
@@ -36,9 +36,11 @@ Gem::Specification.new do |spec|
36
36
  spec.add_development_dependency 'rubocop-rspec', ['~> 1.29']
37
37
 
38
38
  # Runtime
39
+ spec.add_runtime_dependency 'execjs', ['~> 2.7.0']
39
40
  spec.add_runtime_dependency 'json', ['~> 2.1']
40
41
  spec.add_runtime_dependency 'kramdown', ['~> 1.17']
41
42
  spec.add_runtime_dependency 'oga', ['~> 2.15']
42
43
  spec.add_runtime_dependency 'semantic_interval', ['~> 0.1']
44
+ spec.add_runtime_dependency 'therubyracer', ['~> 0.12']
43
45
  spec.add_runtime_dependency 'thor', ['~> 0.20']
44
46
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: yavdb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.4
4
+ version: 0.4.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rodrigo Fernandes
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-11-18 00:00:00.000000000 Z
11
+ date: 2018-11-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - "~>"
123
123
  - !ruby/object:Gem::Version
124
124
  version: '1.29'
125
+ - !ruby/object:Gem::Dependency
126
+ name: execjs
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - "~>"
130
+ - !ruby/object:Gem::Version
131
+ version: 2.7.0
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - "~>"
137
+ - !ruby/object:Gem::Version
138
+ version: 2.7.0
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: json
127
141
  requirement: !ruby/object:Gem::Requirement
@@ -178,6 +192,20 @@ dependencies:
178
192
  - - "~>"
179
193
  - !ruby/object:Gem::Version
180
194
  version: '0.1'
195
+ - !ruby/object:Gem::Dependency
196
+ name: therubyracer
197
+ requirement: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - "~>"
200
+ - !ruby/object:Gem::Version
201
+ version: '0.12'
202
+ type: :runtime
203
+ prerelease: false
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - "~>"
207
+ - !ruby/object:Gem::Version
208
+ version: '0.12'
181
209
  - !ruby/object:Gem::Dependency
182
210
  name: thor
183
211
  requirement: !ruby/object:Gem::Requirement
@@ -227,6 +255,7 @@ files:
227
255
  - lib/yavdb/dtos/advisory.rb
228
256
  - lib/yavdb/source_types/git_repo.rb
229
257
  - lib/yavdb/sources/friends_of_php.rb
258
+ - lib/yavdb/sources/npmjs.rb
230
259
  - lib/yavdb/sources/ossindex.rb
231
260
  - lib/yavdb/sources/ruby_advisory.rb
232
261
  - lib/yavdb/sources/snyk_io.rb