yavdb 0.1.0.pre.alpha.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.circleci/config.yml +48 -0
- data/.gitignore +115 -0
- data/.rspec +3 -0
- data/.rubocop.yml +339 -0
- data/.ruby-version +1 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +85 -0
- data/LICENSE +661 -0
- data/README.md +87 -0
- data/Rakefile +6 -0
- data/bin/console +7 -0
- data/bin/setup +8 -0
- data/bin/vulndb +3 -0
- data/bin/vulnerabilitydb +3 -0
- data/bin/yavdb +5 -0
- data/lib/yavdb.rb +68 -0
- data/lib/yavdb/cli.rb +60 -0
- data/lib/yavdb/constants.rb +34 -0
- data/lib/yavdb/crawler.rb +52 -0
- data/lib/yavdb/database.rb +95 -0
- data/lib/yavdb/dtos/advisory.rb +102 -0
- data/lib/yavdb/source_types/git_repo.rb +35 -0
- data/lib/yavdb/sources/friends_of_php.rb +87 -0
- data/lib/yavdb/sources/nodesecurity_io.rb +120 -0
- data/lib/yavdb/sources/ossindex.rb +137 -0
- data/lib/yavdb/sources/ruby_advisory.rb +117 -0
- data/lib/yavdb/sources/snyk_io.rb +311 -0
- data/lib/yavdb/sources/victims.rb +105 -0
- data/lib/yavdb/utils/cache.rb +96 -0
- data/lib/yavdb/utils/exec.rb +36 -0
- data/lib/yavdb/utils/git.rb +61 -0
- data/lib/yavdb/utils/http.rb +56 -0
- data/lib/yavdb/utils/semver.rb +79 -0
- data/lib/yavdb/utils/zip.rb +64 -0
- data/lib/yavdb/version.rb +21 -0
- data/yavdb.gemspec +44 -0
- metadata +267 -0
data/README.md
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
# Yet Another Vulnerability Database
|
2
|
+
|
3
|
+
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/00298529610b41f4a6ec380550ea45de)](https://www.codacy.com/app/rtfpessoa/yavdb?utm_source=github.com&utm_medium=referral&utm_content=rtfpessoa/yavdb&utm_campaign=Badge_Grade)
|
4
|
+
[![Codacy Badge](https://api.codacy.com/project/badge/Coverage/00298529610b41f4a6ec380550ea45de)](https://www.codacy.com/app/rtfpessoa/yavdb?utm_source=github.com&utm_medium=referral&utm_content=rtfpessoa/yavdb&utm_campaign=Badge_Coverage)
|
5
|
+
[![CircleCI](https://circleci.com/gh/rtfpessoa/yavdb.svg?style=svg)](https://circleci.com/gh/rtfpessoa/yavdb)
|
6
|
+
|
7
|
+
The Free and Open Source vulnerability database.
|
8
|
+
|
9
|
+
This database aims to aggregate multiple sources of vulnerabilities for the most common package managers helping
|
10
|
+
developers identify and fix know vulnerabilities in their apps.
|
11
|
+
|
12
|
+
The sources for this database include
|
13
|
+
[Rubysec](https://rubysec.com/),
|
14
|
+
[snyk](https://snyk.io/),
|
15
|
+
[OSSIndex](https://ossindex.net/),
|
16
|
+
[NodeSecurity](https://nodesecurity.io/),
|
17
|
+
[Friends of PHP](https://github.com/FriendsOfPHP/security-advisories),
|
18
|
+
[Magento Related Security Advisories](https://github.com/victims/victims-cve-db),
|
19
|
+
[Victims CVE Database](https://github.com/victims/victims-cve-db)
|
20
|
+
|
21
|
+
## Prerequisites
|
22
|
+
|
23
|
+
* Ruby 2.3 or newer
|
24
|
+
|
25
|
+
## Installation
|
26
|
+
|
27
|
+
```sh
|
28
|
+
gem install yavdb --pre
|
29
|
+
```
|
30
|
+
|
31
|
+
> Notice the `--pre` in the end
|
32
|
+
|
33
|
+
## TODO:
|
34
|
+
|
35
|
+
#### Tests
|
36
|
+
|
37
|
+
* Sources
|
38
|
+
- [ ] [Rubysec](lib/yavdb/sources/ruby_advisory.rb)
|
39
|
+
- [X] [snyk](lib/yavdb/sources/snyk_io.rb)
|
40
|
+
- [ ] [OSSIndex](lib/yavdb/sources/ossindex.rb)
|
41
|
+
- [X] [NodeSecurity](lib/yavdb/sources/nodesecurity_io.rb)
|
42
|
+
- [ ] [Friends of PHP and Magento Related Security Advisories](lib/yavdb/sources/friends_of_php.rb)
|
43
|
+
- [ ] [Victims CVE Database](lib/yavdb/sources/victims.rb)
|
44
|
+
* Others
|
45
|
+
- [ ] [Advisory](lib/yavdb/dtos/advisory.rb)
|
46
|
+
|
47
|
+
#### Features/Improvements
|
48
|
+
|
49
|
+
- [ ] Merge duplicates
|
50
|
+
- [ ] Scrape [NVD](https://nvd.nist.gov/) for other package manager vulnerabilities
|
51
|
+
- [ ] Find more sources
|
52
|
+
|
53
|
+
### Help
|
54
|
+
|
55
|
+
Commands:
|
56
|
+
yavdb download # Download a previously generated database from the official yavdb repository into yavdb-path.
|
57
|
+
Options: p, [--yavdb-path=YAVDB-PATH] # Default: <HOME>/.yavdb/yavdb
|
58
|
+
yavdb generate # Crawl several sources and generate a local database in database-path.
|
59
|
+
Options: p, [--database-path=DATABASE-PATH] # Default: <PWD>/database
|
60
|
+
yavdb help [COMMAND] # Describe available commands or one specific command
|
61
|
+
yavdb list --package-manager=PACKAGE-MANAGER --package-name=PACKAGE-NAME # List vulnerabilities from database-path of package-name for package-manager.
|
62
|
+
Options: p, [--database-path=DATABASE-PATH] # Default: <HOME>/.yavdb/yavdb/database
|
63
|
+
|
64
|
+
Options:
|
65
|
+
[--verbose], [--no-verbose]
|
66
|
+
|
67
|
+
## Development
|
68
|
+
|
69
|
+
After checking out the repo, run `bin/setup` to install dependencies.
|
70
|
+
Then, run `bundle exec rake spec` to run the tests.
|
71
|
+
You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
72
|
+
|
73
|
+
To install this gem onto your local machine, run `bundle exec rake install`.
|
74
|
+
To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`,
|
75
|
+
which will create a git tag for the version,
|
76
|
+
push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
77
|
+
|
78
|
+
## Contributing
|
79
|
+
|
80
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/rtfpessoa/yavdb.
|
81
|
+
This project is intended to be a safe, welcoming space for collaboration,
|
82
|
+
and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
83
|
+
|
84
|
+
## Copyright
|
85
|
+
|
86
|
+
Copyright (c) 2017-present Rodrigo Fernandes.
|
87
|
+
See [LICENSE](https://github.com/rtfpessoa/yavdb/blob/master/LICENSE) for details.
|
data/Rakefile
ADDED
data/bin/console
ADDED
data/bin/setup
ADDED
data/bin/vulndb
ADDED
data/bin/vulnerabilitydb
ADDED
data/bin/yavdb
ADDED
data/lib/yavdb.rb
ADDED
@@ -0,0 +1,68 @@
|
|
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 'net/http'
|
18
|
+
require 'socket'
|
19
|
+
require 'yaml'
|
20
|
+
require 'semantic_interval'
|
21
|
+
require 'oga'
|
22
|
+
require 'oga/xml/entities'
|
23
|
+
|
24
|
+
require_relative 'yavdb/constants'
|
25
|
+
require_relative 'yavdb/crawler'
|
26
|
+
require_relative 'yavdb/database'
|
27
|
+
require_relative 'yavdb/utils/exec'
|
28
|
+
require_relative 'yavdb/utils/http'
|
29
|
+
require_relative 'yavdb/utils/git'
|
30
|
+
|
31
|
+
module YAVDB
|
32
|
+
class API
|
33
|
+
|
34
|
+
# List vulnerabilities from database_path of package_name for package_manager.
|
35
|
+
#
|
36
|
+
# @param package_manager [String] the package manager.
|
37
|
+
# @param package_name [String] the package_name.
|
38
|
+
# @param database_path [String] the local path to the database.
|
39
|
+
# @return [Array<Advisory>] the array of vulnerabilities.
|
40
|
+
def self.list_vulnerabilities(package_manager,
|
41
|
+
package_name,
|
42
|
+
database_path = YAVDB::Constants::DEFAULT_YAVDB_PATH)
|
43
|
+
YAVDB::Database.search(database_path, package_manager, package_name)
|
44
|
+
end
|
45
|
+
|
46
|
+
# Crawl several sources and generate a local database in database_path.
|
47
|
+
#
|
48
|
+
# @param database_path [String] the local path to the database.
|
49
|
+
def self.generate_database(database_path = YAVDB::Constants::DEFAULT_GENERATE_DATABASE_PATH)
|
50
|
+
vulnerabilities = YAVDB::Crawler.vulnerabilities
|
51
|
+
YAVDB::Database.save(database_path, vulnerabilities)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Download a previously generated database from the official yavdb repository into yavdb_path.
|
55
|
+
#
|
56
|
+
# @param force_update [Boolean] force an update of the database if it already exists but is in a previous version.
|
57
|
+
# @param yavdb_path [String] the local path to the yavdb repository with the database.
|
58
|
+
# @param yavdb_url [String] the yavdb url to clone the database repository from.
|
59
|
+
# @param yavdb_branch [String] the yavdb branch with the database.
|
60
|
+
def self.download_database(force_update = false,
|
61
|
+
yavdb_path = YAVDB::Constants::DEFAULT_YAVDB_PATH,
|
62
|
+
yavdb_url = YAVDB::Constants::YAVDB_DB_URL,
|
63
|
+
yavdb_branch = YAVDB::Constants::YAVDB_DB_BRANCH)
|
64
|
+
YAVDB::Utils::Git.download_or_update(yavdb_path, yavdb_url, yavdb_branch, force_update)
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
end
|
data/lib/yavdb/cli.rb
ADDED
@@ -0,0 +1,60 @@
|
|
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 'thor'
|
18
|
+
|
19
|
+
require_relative 'constants'
|
20
|
+
require_relative '../yavdb'
|
21
|
+
|
22
|
+
module YAVDB
|
23
|
+
class CLI < Thor
|
24
|
+
|
25
|
+
map '--version' => :version
|
26
|
+
|
27
|
+
class_option('verbose', :type => :boolean, :default => false)
|
28
|
+
|
29
|
+
method_option('package-manager', :alias => :m, :type => :string, :required => true)
|
30
|
+
method_option('package-name', :alias => :n, :type => :string, :required => true)
|
31
|
+
method_option('database-path', :type => :string, :aliases => :p, :default => YAVDB::Constants::DEFAULT_YAVDB_DATABASE_PATH)
|
32
|
+
desc('list', 'List vulnerabilities from database-path of package-name for package-manager.')
|
33
|
+
|
34
|
+
def list
|
35
|
+
package_manager = options['package-manager']
|
36
|
+
|
37
|
+
unless YAVDB::Constants::POSSIBLE_PACKAGE_MANAGERS.include?(package_manager)
|
38
|
+
puts "Package manager #{package_manager} is not supported yet."
|
39
|
+
exit(1)
|
40
|
+
end
|
41
|
+
|
42
|
+
API.list_vulnerabilities(package_manager, options['package-name'], options['database-path'])
|
43
|
+
end
|
44
|
+
|
45
|
+
method_option('database-path', :type => :string, :aliases => :p, :default => YAVDB::Constants::DEFAULT_GENERATE_DATABASE_PATH)
|
46
|
+
desc('generate', 'Crawl several sources and generate a local database in database-path.')
|
47
|
+
|
48
|
+
def generate
|
49
|
+
API.generate_database(options['database-path'])
|
50
|
+
end
|
51
|
+
|
52
|
+
method_option('yavdb-path', :type => :string, :aliases => :p, :default => YAVDB::Constants::DEFAULT_YAVDB_PATH)
|
53
|
+
desc('download', 'Download a previously generated database from the official yavdb repository into yavdb-path.')
|
54
|
+
|
55
|
+
def download
|
56
|
+
API.download_database(options['yavdb-path'])
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,34 @@
|
|
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
|
+
module YAVDB
|
18
|
+
module Constants
|
19
|
+
|
20
|
+
DEBUG = ENV['debug'].freeze
|
21
|
+
|
22
|
+
YAVDB_DB_URL = 'https://github.com/rtfpessoa/yavdb.git'
|
23
|
+
YAVDB_DB_BRANCH = 'database'
|
24
|
+
|
25
|
+
DEFAULT_GENERATE_DATABASE_PATH = File.expand_path(File.join(Dir.pwd, ['database'])).freeze
|
26
|
+
|
27
|
+
DEFAULT_YAVDB_PATH = File.expand_path(File.join(ENV['HOME'], '.yavdb', 'yavdb')).freeze
|
28
|
+
DEFAULT_YAVDB_DATABASE_PATH = File.expand_path(File.join(DEFAULT_YAVDB_PATH, 'database')).freeze
|
29
|
+
DEFAULT_CACHE_PATH = File.expand_path(File.join(ENV['HOME'], '.yavdb', 'cache')).freeze
|
30
|
+
|
31
|
+
POSSIBLE_PACKAGE_MANAGERS = ['npm', 'rubygems', 'maven', 'nuget', 'packagist', 'pypi', 'go'].freeze
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,52 @@
|
|
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
|
+
Dir[File.expand_path('sources/*.rb', __dir__)].each do |file|
|
18
|
+
require file
|
19
|
+
end
|
20
|
+
|
21
|
+
module YAVDB
|
22
|
+
class Crawler
|
23
|
+
|
24
|
+
def self.sources
|
25
|
+
YAVDB::Sources.constants
|
26
|
+
.map { |c| YAVDB::Sources.const_get(c) }
|
27
|
+
.sort_by { |c| c.to_s.downcase }
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.vulnerabilities
|
31
|
+
vulns = sources.map { |src| src::Client.advisories }.flatten
|
32
|
+
clean_vulnerability_versions(vulns)
|
33
|
+
end
|
34
|
+
|
35
|
+
class << self
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def clean_vulnerability_versions(vulnerabilities)
|
40
|
+
vulnerabilities
|
41
|
+
.map do |vln|
|
42
|
+
vln.vulnerable_versions = YAVDB::Utils::SemVer.clean_versions(vln.vulnerable_versions)
|
43
|
+
vln.unaffected_versions = YAVDB::Utils::SemVer.clean_versions(vln.unaffected_versions)
|
44
|
+
vln.patched_versions = YAVDB::Utils::SemVer.clean_versions(vln.patched_versions)
|
45
|
+
vln
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,95 @@
|
|
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_relative 'constants'
|
18
|
+
require_relative 'utils/semver'
|
19
|
+
|
20
|
+
module YAVDB
|
21
|
+
class Database
|
22
|
+
|
23
|
+
def self.save(database_path, vulns)
|
24
|
+
vulns_grouped_by_package_manager = group_by_package_manager(vulns)
|
25
|
+
save_to_file(database_path, vulns_grouped_by_package_manager)
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.search(database_path, package_manager, package_name)
|
29
|
+
package_file_path = package_path(database_path, package_manager, package_name)
|
30
|
+
|
31
|
+
if File.exist?(package_file_path)
|
32
|
+
YAVDB::Advisory.load(package_file_path)
|
33
|
+
else
|
34
|
+
[]
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
class << self
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def group_by_package_manager(vulns)
|
43
|
+
vulns
|
44
|
+
.group_by(&:package_manager)
|
45
|
+
.map do |package_manager, vunerabilities_by_pm|
|
46
|
+
|
47
|
+
puts "#{package_manager}: #{vunerabilities_by_pm.length}"
|
48
|
+
|
49
|
+
vunerabilities_by_pm =
|
50
|
+
vunerabilities_by_pm
|
51
|
+
.group_by(&:affected_package)
|
52
|
+
.map do |package, vunerabilities_by_p|
|
53
|
+
[package, vunerabilities_by_p]
|
54
|
+
end.to_h
|
55
|
+
|
56
|
+
[package_manager, vunerabilities_by_pm]
|
57
|
+
end.to_h
|
58
|
+
end
|
59
|
+
|
60
|
+
def save_to_file(database_path, vulns)
|
61
|
+
vulns.map do |package_manager, vunerabilities_by_pm|
|
62
|
+
vunerabilities_by_pm.map do |package, vunerabilities_by_p|
|
63
|
+
package_path = package_path(database_path, package_manager, package)
|
64
|
+
package_path_directory = File.dirname(package_path)
|
65
|
+
FileUtils.mkdir_p(package_path_directory) unless File.exist?(package_path_directory)
|
66
|
+
|
67
|
+
File.open(package_path, 'wb') do |file|
|
68
|
+
package_vulns_yml_str = vunerabilities_by_p
|
69
|
+
.map(&:to_map)
|
70
|
+
.to_yaml(
|
71
|
+
:Indent => 4,
|
72
|
+
:SortKeys => true,
|
73
|
+
:UseHeader => true,
|
74
|
+
:UseVersion => true,
|
75
|
+
:ExplicitTypes => true,
|
76
|
+
:BestWidth => 80,
|
77
|
+
:UseFold => true,
|
78
|
+
:UseBlock => true,
|
79
|
+
:Encoding => :Utf8
|
80
|
+
)
|
81
|
+
|
82
|
+
file.puts(package_vulns_yml_str)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def package_path(database_path, package_manager, package_name)
|
89
|
+
File.expand_path(File.join(database_path, package_manager, "#{package_name}.yml"))
|
90
|
+
end
|
91
|
+
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|