yavdb 0.1.0.pre.alpha.2

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.
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
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/console ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'yavdb'
5
+
6
+ require 'irb'
7
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+
3
+ set -euo pipefail
4
+
5
+ IFS=$'\n\t'
6
+ set -vx
7
+
8
+ bundle install
data/bin/vulndb ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ load File.expand_path('../yavdb', __FILE__)
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ load File.expand_path('../yavdb', __FILE__)
data/bin/yavdb ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'yavdb/cli'
4
+
5
+ YAVDB::CLI.start(ARGV)
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