package-audit 0.2.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/package/audit/cli.rb +42 -42
- data/lib/package/audit/const/cmd.rb +3 -3
- data/lib/package/audit/const/fields.rb +4 -4
- data/lib/package/audit/const/file.rb +1 -0
- data/lib/package/audit/const/yaml.rb +13 -0
- data/lib/package/audit/enum/option.rb +13 -0
- data/lib/package/audit/enum/report.rb +12 -0
- data/lib/package/audit/enum/technology.rb +14 -0
- data/lib/package/audit/formatter/risk.rb +1 -1
- data/lib/package/audit/formatter/version.rb +1 -1
- data/lib/package/audit/formatter/version_date.rb +1 -1
- data/lib/package/audit/formatter/vulnerability.rb +1 -1
- data/lib/package/audit/{package.rb → models/package.rb} +8 -7
- data/lib/package/audit/npm/node_collection.rb +25 -14
- data/lib/package/audit/npm/vulnerability_finder.rb +4 -3
- data/lib/package/audit/npm/yarn_lock_parser.rb +10 -6
- data/lib/package/audit/ruby/bundler_specs.rb +16 -9
- data/lib/package/audit/ruby/gem_collection.rb +36 -15
- data/lib/package/audit/ruby/gem_meta_data.rb +1 -1
- data/lib/package/audit/ruby/vulnerability_finder.rb +4 -3
- data/lib/package/audit/services/command_parser.rb +103 -0
- data/lib/package/audit/services/package_filter.rb +39 -0
- data/lib/package/audit/services/package_finder.rb +58 -0
- data/lib/package/audit/{printer.rb → services/package_printer.rb} +12 -11
- data/lib/package/audit/{risk_calculator.rb → services/risk_calculator.rb} +8 -4
- data/lib/package/audit/technology/detector.rb +40 -0
- data/lib/package/audit/technology/validator.rb +56 -0
- data/lib/package/audit/util/summary_printer.rb +22 -11
- data/lib/package/audit/version.rb +1 -1
- data/sig/package/audit/cli.rbs +2 -0
- data/sig/package/audit/const/fields.rbs +2 -1
- data/sig/package/audit/const/file.rbs +1 -0
- data/sig/package/audit/const/yaml.rbs +13 -0
- data/sig/package/audit/enum/option.rbs +13 -0
- data/sig/package/audit/enum/report.rbs +12 -0
- data/sig/package/audit/enum/technology.rbs +12 -0
- data/sig/package/audit/{package.rbs → models/package.rbs} +3 -1
- data/sig/package/audit/{risk.rbs → models/risk.rbs} +1 -1
- data/sig/package/audit/npm/node_collection.rbs +4 -5
- data/sig/package/audit/npm/vulnerability_finder.rbs +3 -2
- data/sig/package/audit/npm/yarn_lock_parser.rbs +1 -0
- data/sig/package/audit/ruby/bundler_specs.rbs +2 -2
- data/sig/package/audit/ruby/gem_collection.rbs +11 -4
- data/sig/package/audit/ruby/vulnerability_finder.rbs +3 -0
- data/sig/package/audit/services/command_parser.rbs +31 -0
- data/sig/package/audit/services/package_filter.rbs +19 -0
- data/sig/package/audit/services/package_finder.rbs +23 -0
- data/sig/package/audit/{printer.rbs → services/package_printer.rbs} +3 -3
- data/sig/package/audit/technology/detector.rbs +19 -0
- data/sig/package/audit/technology/validator.rbs +19 -0
- data/sig/package/audit/util/summary_printer.rbs +5 -5
- metadata +30 -14
- data/lib/package/audit/command_service.rb +0 -187
- data/sig/package/audit/command_service.rbs +0 -29
- /data/lib/package/audit/{risk.rb → models/risk.rb} +0 -0
- /data/lib/package/audit/{duplicate_package_merger.rb → services/duplicate_package_merger.rb} +0 -0
- /data/sig/package/audit/{duplicate_package_merger.rbs → services/duplicate_package_merger.rbs} +0 -0
- /data/sig/package/audit/{risk_calculator.rbs → services/risk_calculator.rbs} +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d30d08ba36373c75427371f922cb0a5819a021868bf82001428e0541571df9f8
|
4
|
+
data.tar.gz: ac4dce54e3905dd56de9b137a62101de7267262c1f6b0310e4697c8f016a36b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 00be4151f4f124614d117a739a558f9f2816f0f72095f222ddadf5101a6d089b40bdc5369c4a68c9b096b1547932561394f1fee5ca58712e13a4909c4a8c9558
|
7
|
+
data.tar.gz: f224c2c2fe2ff39586d20989ef6999d7b2a52acd2276dcdd9895441105ccaebc5991523676b88545a5afa96d4ffcac10291ab76dfab735b65d42aabc4598d7e4
|
data/lib/package/audit/cli.rb
CHANGED
@@ -1,11 +1,8 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative '
|
3
|
-
require_relative '
|
4
|
-
require_relative '
|
5
|
-
require_relative '
|
6
|
-
require_relative './ruby/gem_collection'
|
7
|
-
require_relative './npm/node_collection'
|
8
|
-
require_relative './command_service'
|
1
|
+
require_relative 'const/file'
|
2
|
+
require_relative 'const/time'
|
3
|
+
require_relative 'enum/option'
|
4
|
+
require_relative 'services/command_parser'
|
5
|
+
require_relative 'version'
|
9
6
|
|
10
7
|
require 'json'
|
11
8
|
require 'thor'
|
@@ -15,57 +12,52 @@ module Package
|
|
15
12
|
class CLI < Thor
|
16
13
|
default_task :report
|
17
14
|
|
15
|
+
class_option Enum::Option::CONFIG,
|
16
|
+
aliases: '-c', banner: 'FILE',
|
17
|
+
desc: "Path to a custom configuration file, default: #{Const::File::CONFIG})"
|
18
|
+
class_option Enum::Option::TECHNOLOGY,
|
19
|
+
aliases: '-t', repeatable: true,
|
20
|
+
desc: 'Technology to be audited (repeat this flag for each technology)'
|
21
|
+
class_option Enum::Option::INCLUDE_IGNORED,
|
22
|
+
type: :boolean, default: false,
|
23
|
+
desc: 'Include packages ignored by a configuration file'
|
24
|
+
class_option Enum::Option::CSV,
|
25
|
+
type: :boolean, default: false,
|
26
|
+
desc: 'Output reports using comma separated values (CSV)'
|
27
|
+
class_option Enum::Option::CSV_EXCLUDE_HEADERS,
|
28
|
+
type: :boolean, default: false,
|
29
|
+
desc: "Hide headers when using the --#{Enum::Option::CSV} option"
|
30
|
+
|
31
|
+
map '-v' => :version
|
18
32
|
map '--version' => :version
|
19
33
|
|
20
|
-
desc 'report', 'Show a report of potentially deprecated, outdated or vulnerable packages'
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
def report
|
25
|
-
within_rescue_block do
|
26
|
-
exit CommandService.new(Dir.pwd, options).all
|
27
|
-
end
|
34
|
+
desc 'report [DIR]', 'Show a report of potentially deprecated, outdated or vulnerable packages'
|
35
|
+
def report(dir = Dir.pwd)
|
36
|
+
within_rescue_block { exit CommandParser.new(dir, options, Enum::Report::ALL).run }
|
28
37
|
end
|
29
38
|
|
30
|
-
desc 'deprecated',
|
39
|
+
desc 'deprecated [DIR]',
|
31
40
|
"Show packages with no updates by author for at least #{Const::Time::YEARS_ELAPSED_TO_BE_OUTDATED} years"
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
def deprecated
|
36
|
-
within_rescue_block do
|
37
|
-
exit CommandService.new(Dir.pwd, options).deprecated
|
38
|
-
end
|
41
|
+
def deprecated(dir = Dir.pwd)
|
42
|
+
within_rescue_block { exit CommandParser.new(dir, options, Enum::Report::DEPRECATED).run }
|
39
43
|
end
|
40
44
|
|
41
|
-
desc 'outdated', 'Show packages that are out of date'
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
def outdated
|
46
|
-
within_rescue_block do
|
47
|
-
exit CommandService.new(Dir.pwd, options).outdated
|
48
|
-
end
|
45
|
+
desc 'outdated [DIR]', 'Show packages that are out of date'
|
46
|
+
def outdated(dir = Dir.pwd)
|
47
|
+
within_rescue_block { exit CommandParser.new(dir, options, Enum::Report::OUTDATED).run }
|
49
48
|
end
|
50
49
|
|
51
|
-
desc 'vulnerable', 'Show packages and their dependencies that have security vulnerabilities'
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
def vulnerable
|
56
|
-
within_rescue_block do
|
57
|
-
exit CommandService.new(Dir.pwd, options).vulnerable
|
58
|
-
end
|
50
|
+
desc 'vulnerable [DIR]', 'Show packages and their dependencies that have security vulnerabilities'
|
51
|
+
def vulnerable(dir = Dir.pwd)
|
52
|
+
within_rescue_block { exit CommandParser.new(dir, options, Enum::Report::VULNERABLE).run }
|
59
53
|
end
|
60
54
|
|
61
55
|
desc 'risk', 'Print information on how risk is calculated'
|
62
|
-
|
63
56
|
def risk
|
64
57
|
Util::SummaryPrinter.risk
|
65
58
|
end
|
66
59
|
|
67
60
|
desc 'version', 'Print the currently installed version of the package-audit gem'
|
68
|
-
|
69
61
|
def version
|
70
62
|
puts "package-audit #{VERSION}"
|
71
63
|
end
|
@@ -74,6 +66,14 @@ module Package
|
|
74
66
|
true
|
75
67
|
end
|
76
68
|
|
69
|
+
def method_missing(command, *args)
|
70
|
+
invoke :report, [command], args
|
71
|
+
end
|
72
|
+
|
73
|
+
def respond_to_missing?
|
74
|
+
true
|
75
|
+
end
|
76
|
+
|
77
77
|
private
|
78
78
|
|
79
79
|
def within_rescue_block
|
@@ -2,14 +2,14 @@ module Package
|
|
2
2
|
module Audit
|
3
3
|
module Const
|
4
4
|
module Cmd
|
5
|
-
BUNDLE_AUDIT = 'bundle
|
6
|
-
BUNDLE_AUDIT_JSON = 'bundle
|
5
|
+
BUNDLE_AUDIT = 'bundle-audit check --update'
|
6
|
+
BUNDLE_AUDIT_JSON = 'bundle-audit check --update --quiet --format json %s'
|
7
7
|
|
8
8
|
NPM_AUDIT = 'npm audit'
|
9
9
|
NPM_AUDIT_JSON = 'npm audit --json'
|
10
10
|
|
11
11
|
YARN_AUDIT = 'yarn audit'
|
12
|
-
YARN_AUDIT_JSON = 'yarn audit --json'
|
12
|
+
YARN_AUDIT_JSON = 'yarn audit --json --cwd %s'
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -2,7 +2,7 @@ module Package
|
|
2
2
|
module Audit
|
3
3
|
module Const
|
4
4
|
module Fields
|
5
|
-
|
5
|
+
AVAILABLE = %i[
|
6
6
|
name
|
7
7
|
version
|
8
8
|
version_date
|
@@ -14,15 +14,15 @@ module Package
|
|
14
14
|
risk_explanation
|
15
15
|
]
|
16
16
|
|
17
|
-
|
18
|
-
|
17
|
+
ALL = %i[name version latest_version latest_version_date groups vulnerabilities risk_type risk_explanation]
|
18
|
+
DEPRECATED = %i[name version latest_version latest_version_date groups]
|
19
19
|
OUTDATED = %i[name version latest_version latest_version_date groups]
|
20
|
+
VULNERABLE = %i[name version latest_version groups vulnerabilities]
|
20
21
|
|
21
22
|
# the names of these fields must match the instance variables in the Dependency class
|
22
23
|
HEADERS = {
|
23
24
|
name: 'Package',
|
24
25
|
version: 'Version',
|
25
|
-
version_date: 'Date',
|
26
26
|
latest_version: 'Latest',
|
27
27
|
latest_version_date: 'Latest Date',
|
28
28
|
groups: 'Groups',
|
@@ -1,18 +1,19 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative '
|
3
|
-
require_relative '
|
4
|
-
require_relative '
|
5
|
-
require_relative '
|
1
|
+
require_relative '../enum/environment'
|
2
|
+
require_relative '../enum/risk_explanation'
|
3
|
+
require_relative '../enum/risk_type'
|
4
|
+
require_relative '../services/risk_calculator'
|
5
|
+
require_relative 'risk'
|
6
6
|
|
7
7
|
module Package
|
8
8
|
module Audit
|
9
9
|
class Package
|
10
|
-
attr_reader :name, :version
|
10
|
+
attr_reader :name, :version, :technology
|
11
11
|
attr_accessor :groups, :version_date, :latest_version, :latest_version_date, :vulnerabilities
|
12
12
|
|
13
|
-
def initialize(name, version, **attr)
|
13
|
+
def initialize(name, version, technology, **attr)
|
14
14
|
@name = name.to_s
|
15
15
|
@version = version.to_s
|
16
|
+
@technology = technology.to_s
|
16
17
|
@groups = []
|
17
18
|
@vulnerabilities = []
|
18
19
|
@risks = []
|
@@ -1,23 +1,34 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative '
|
3
|
-
require_relative '
|
4
|
-
require_relative '
|
1
|
+
require_relative '../const/file'
|
2
|
+
require_relative '../services/duplicate_package_merger'
|
3
|
+
require_relative 'npm_meta_data'
|
4
|
+
require_relative 'vulnerability_finder'
|
5
|
+
require_relative 'yarn_lock_parser'
|
5
6
|
|
6
7
|
module Package
|
7
8
|
module Audit
|
8
9
|
module Npm
|
9
10
|
class NodeCollection
|
10
|
-
|
11
|
-
PACKAGE_LOCK = 'package-lock.json'
|
12
|
-
YARN_LOCK = 'yarn.lock'
|
13
|
-
|
14
|
-
def initialize(dir)
|
11
|
+
def initialize(dir, report)
|
15
12
|
@dir = dir
|
13
|
+
@report = report
|
14
|
+
end
|
15
|
+
|
16
|
+
def fetch
|
17
|
+
case @report
|
18
|
+
when Enum::Report::DEPRECATED
|
19
|
+
deprecated
|
20
|
+
when Enum::Report::OUTDATED
|
21
|
+
outdated
|
22
|
+
when Enum::Report::VULNERABLE
|
23
|
+
vulnerable
|
24
|
+
else
|
25
|
+
all
|
26
|
+
end
|
16
27
|
end
|
17
28
|
|
18
29
|
def all
|
19
30
|
implicit_pkgs = fetch_from_lock_file
|
20
|
-
vulnerable_pkgs = VulnerabilityFinder.new(implicit_pkgs).run
|
31
|
+
vulnerable_pkgs = VulnerabilityFinder.new(@dir, implicit_pkgs).run
|
21
32
|
pkgs = NpmMetaData.new(vulnerable_pkgs + implicit_pkgs).fetch.filter(&:risk?)
|
22
33
|
DuplicatePackageMerger.new(pkgs).run
|
23
34
|
end
|
@@ -36,7 +47,7 @@ module Package
|
|
36
47
|
|
37
48
|
def vulnerable
|
38
49
|
implicit_pkgs = fetch_from_lock_file
|
39
|
-
vulnerable_pkgs = VulnerabilityFinder.new(implicit_pkgs).run
|
50
|
+
vulnerable_pkgs = VulnerabilityFinder.new(@dir, implicit_pkgs).run
|
40
51
|
pkgs = NpmMetaData.new(vulnerable_pkgs).fetch
|
41
52
|
DuplicatePackageMerger.new(pkgs).run
|
42
53
|
end
|
@@ -44,7 +55,7 @@ module Package
|
|
44
55
|
private
|
45
56
|
|
46
57
|
def fetch_from_package_json
|
47
|
-
package_json = JSON.parse(File.read("#{@dir}/#{PACKAGE_JSON}"), symbolize_names: true)
|
58
|
+
package_json = JSON.parse(File.read("#{@dir}/#{Const::File::PACKAGE_JSON}"), symbolize_names: true)
|
48
59
|
default_deps = package_json[:dependencies] || {}
|
49
60
|
dev_deps = package_json[:devDependencies] || {}
|
50
61
|
[default_deps, dev_deps]
|
@@ -52,8 +63,8 @@ module Package
|
|
52
63
|
|
53
64
|
def fetch_from_lock_file
|
54
65
|
default_deps, dev_deps = fetch_from_package_json
|
55
|
-
if File.exist?("#{@dir}/#{YARN_LOCK}")
|
56
|
-
YarnLockParser.new("#{@dir}/#{YARN_LOCK}").fetch(default_deps || {}, dev_deps || {})
|
66
|
+
if File.exist?("#{@dir}/#{Const::File::YARN_LOCK}")
|
67
|
+
YarnLockParser.new("#{@dir}/#{Const::File::YARN_LOCK}").fetch(default_deps || {}, dev_deps || {})
|
57
68
|
else
|
58
69
|
[]
|
59
70
|
end
|
@@ -7,13 +7,14 @@ module Package
|
|
7
7
|
class VulnerabilityFinder
|
8
8
|
AUDIT_ADVISORY_REGEX = /^{"type":"auditAdvisory".*$/
|
9
9
|
|
10
|
-
def initialize(pkgs)
|
10
|
+
def initialize(dir, pkgs)
|
11
|
+
@dir = dir
|
11
12
|
@pkg_hash = pkgs.to_h { |pkg| [pkg.name, pkg] }
|
12
13
|
@vuln_hash = {}
|
13
14
|
end
|
14
15
|
|
15
16
|
def run
|
16
|
-
json_string_lines = `#{Const::Cmd::YARN_AUDIT_JSON}`
|
17
|
+
json_string_lines = `#{format(Const::Cmd::YARN_AUDIT_JSON, @dir)}`
|
17
18
|
array = json_string_lines.scan(AUDIT_ADVISORY_REGEX)
|
18
19
|
|
19
20
|
vulnerability_json_array = JSON.parse("[#{array.join(',')}]", symbolize_names: true)
|
@@ -33,7 +34,7 @@ module Package
|
|
33
34
|
full_name = "#{name}@#{version}"
|
34
35
|
vulnerability = advisory[:severity] || Enum::VulnerabilityType::UNKNOWN
|
35
36
|
|
36
|
-
@vuln_hash[full_name] = Package.new(name, version) unless @vuln_hash.key? full_name
|
37
|
+
@vuln_hash[full_name] = Package.new(name, version, 'node') unless @vuln_hash.key? full_name
|
37
38
|
@vuln_hash[full_name].update vulnerabilities: @vuln_hash[full_name].vulnerabilities + [vulnerability]
|
38
39
|
@vuln_hash[full_name].update groups: @pkg_hash[parent_name].groups
|
39
40
|
end
|
@@ -3,7 +3,8 @@ module Package
|
|
3
3
|
module Npm
|
4
4
|
class YarnLockParser
|
5
5
|
def initialize(yarn_lock_path)
|
6
|
-
@
|
6
|
+
@yarn_lock_file = File.read(yarn_lock_path)
|
7
|
+
@yarn_lock_path = yarn_lock_path
|
7
8
|
end
|
8
9
|
|
9
10
|
def fetch(default_deps, dev_deps)
|
@@ -11,7 +12,7 @@ module Package
|
|
11
12
|
default_deps.merge(dev_deps).each do |dep_name, expected_version|
|
12
13
|
pkg_block = fetch_package_block(dep_name, expected_version)
|
13
14
|
version = fetch_package_version(dep_name, pkg_block)
|
14
|
-
pks = Package.new(dep_name.to_s, version)
|
15
|
+
pks = Package.new(dep_name.to_s, version, 'node')
|
15
16
|
pks.update groups: dev_deps.key?(dep_name) ? %i[development] : %i[default development]
|
16
17
|
pkgs << pks
|
17
18
|
end
|
@@ -22,17 +23,20 @@ module Package
|
|
22
23
|
|
23
24
|
def fetch_package_block(dep_name, expected_version)
|
24
25
|
regex = /#{Regexp.escape(dep_name)}@#{Regexp.escape(expected_version)}.*?:.*?(\n\n|\z)/m
|
25
|
-
blocks = @
|
26
|
+
blocks = @yarn_lock_file.match(regex)
|
26
27
|
if blocks.nil? || blocks[0].nil?
|
27
|
-
raise NoMatchingPatternError, "Unable to find #{dep_name} in #{@yarn_lock_path}"
|
28
|
+
raise NoMatchingPatternError, "Unable to find \"#{dep_name}\" in #{@yarn_lock_path}"
|
28
29
|
end
|
29
30
|
|
30
31
|
blocks[0] || ''
|
31
32
|
end
|
32
33
|
|
33
34
|
def fetch_package_version(dep_name, pkg_block)
|
34
|
-
version = pkg_block.match(/version
|
35
|
-
|
35
|
+
version = pkg_block.match(/version"?\s*"(.*?)"/)&.captures&.[](0)
|
36
|
+
if version.nil?
|
37
|
+
raise NoMatchingPatternError,
|
38
|
+
"Unable to find the version of \"#{dep_name}\" in #{@yarn_lock_path}"
|
39
|
+
end
|
36
40
|
|
37
41
|
version || '0.0.0.0'
|
38
42
|
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require_relative '../package'
|
2
|
-
require_relative '
|
3
|
-
require_relative '
|
1
|
+
require_relative '../models/package'
|
2
|
+
require_relative 'gem_meta_data'
|
3
|
+
require_relative 'vulnerability_finder'
|
4
4
|
|
5
5
|
require 'bundler'
|
6
6
|
|
@@ -8,16 +8,23 @@ module Package
|
|
8
8
|
module Audit
|
9
9
|
module Ruby
|
10
10
|
class BundlerSpecs
|
11
|
-
def self.all
|
12
|
-
Bundler.
|
11
|
+
def self.all(dir)
|
12
|
+
Bundler.with_unbundled_env do
|
13
|
+
ENV['BUNDLE_GEMFILE'] = "#{dir}/Gemfile"
|
14
|
+
Bundler.ui.silence { Bundler.definition.resolve }
|
15
|
+
end
|
13
16
|
end
|
14
17
|
|
15
|
-
def self.gemfile
|
16
|
-
current_dependencies = Bundler.
|
17
|
-
|
18
|
+
def self.gemfile(dir)
|
19
|
+
current_dependencies = Bundler.with_unbundled_env do
|
20
|
+
ENV['BUNDLE_GEMFILE'] = "#{dir}/Gemfile"
|
21
|
+
Bundler.reset!
|
22
|
+
Bundler.ui.silence do
|
23
|
+
Bundler.load.dependencies.to_h { |dep| [dep.name, dep] }
|
24
|
+
end
|
18
25
|
end
|
19
26
|
|
20
|
-
gemfile_specs, = all.partition do |spec|
|
27
|
+
gemfile_specs, = all(dir).partition do |spec|
|
21
28
|
current_dependencies.key? spec.name
|
22
29
|
end
|
23
30
|
gemfile_specs
|
@@ -1,35 +1,56 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative '
|
3
|
-
require_relative '../duplicate_package_merger'
|
1
|
+
require_relative '../enum/report'
|
2
|
+
require_relative '../enum/risk_type'
|
3
|
+
require_relative '../services/duplicate_package_merger'
|
4
|
+
require_relative 'bundler_specs'
|
4
5
|
|
5
6
|
module Package
|
6
7
|
module Audit
|
7
8
|
module Ruby
|
8
9
|
class GemCollection
|
9
|
-
def
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
def initialize(dir, report)
|
11
|
+
@dir = dir
|
12
|
+
@report = report
|
13
|
+
end
|
14
|
+
|
15
|
+
def fetch
|
16
|
+
case @report
|
17
|
+
when Enum::Report::DEPRECATED
|
18
|
+
deprecated
|
19
|
+
when Enum::Report::OUTDATED
|
20
|
+
outdated
|
21
|
+
when Enum::Report::VULNERABLE
|
22
|
+
vulnerable
|
23
|
+
else
|
24
|
+
all
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def all
|
31
|
+
specs = BundlerSpecs.gemfile(@dir)
|
32
|
+
pkgs = specs.map { |spec| Package.new(spec.name, spec.version, Enum::Technology::RUBY) }
|
33
|
+
vulnerable_pkgs = VulnerabilityFinder.new(@dir).run
|
13
34
|
pkgs = GemMetaData.new(pkgs + vulnerable_pkgs).fetch.filter(&:risk?)
|
14
35
|
DuplicatePackageMerger.new(pkgs).run
|
15
36
|
end
|
16
37
|
|
17
|
-
def
|
18
|
-
specs = BundlerSpecs.gemfile
|
19
|
-
pkgs = specs.map { |spec| Package.new(spec.name, spec.version) }
|
38
|
+
def deprecated
|
39
|
+
specs = BundlerSpecs.gemfile(@dir)
|
40
|
+
pkgs = specs.map { |spec| Package.new(spec.name, spec.version, Enum::Technology::RUBY) }
|
20
41
|
pkgs = GemMetaData.new(pkgs).fetch.filter(&:deprecated?)
|
21
42
|
DuplicatePackageMerger.new(pkgs).run
|
22
43
|
end
|
23
44
|
|
24
|
-
def
|
25
|
-
specs = include_implicit ? BundlerSpecs.all : BundlerSpecs.gemfile
|
26
|
-
pkgs = specs.map { |spec| Package.new(spec.name, spec.version) }
|
45
|
+
def outdated(include_implicit: false)
|
46
|
+
specs = include_implicit ? BundlerSpecs.all(@dir) : BundlerSpecs.gemfile(@dir)
|
47
|
+
pkgs = specs.map { |spec| Package.new(spec.name, spec.version, Enum::Technology::RUBY) }
|
27
48
|
pkgs = GemMetaData.new(pkgs).fetch.filter(&:outdated?)
|
28
49
|
DuplicatePackageMerger.new(pkgs).run
|
29
50
|
end
|
30
51
|
|
31
|
-
def
|
32
|
-
pkgs = VulnerabilityFinder.new.run
|
52
|
+
def vulnerable
|
53
|
+
pkgs = VulnerabilityFinder.new(@dir).run
|
33
54
|
pkgs = GemMetaData.new(pkgs).fetch.filter(&:vulnerable?)
|
34
55
|
DuplicatePackageMerger.new(pkgs).run
|
35
56
|
end
|
@@ -5,12 +5,13 @@ module Package
|
|
5
5
|
module Audit
|
6
6
|
module Ruby
|
7
7
|
class VulnerabilityFinder
|
8
|
-
def initialize
|
8
|
+
def initialize(dir)
|
9
|
+
@dir = dir
|
9
10
|
@vuln_hash = {}
|
10
11
|
end
|
11
12
|
|
12
13
|
def run
|
13
|
-
json_result = `#{Const::Cmd::BUNDLE_AUDIT_JSON}`
|
14
|
+
json_result = `#{format(Const::Cmd::BUNDLE_AUDIT_JSON, @dir)}`
|
14
15
|
vulnerability_json_array = JSON.parse(json_result, symbolize_names: true)[:results]
|
15
16
|
vulnerability_json_array.each do |vulnerability_json|
|
16
17
|
update_meta_data(vulnerability_json)
|
@@ -25,7 +26,7 @@ module Package
|
|
25
26
|
version = json[:gem][:version]
|
26
27
|
full_name = "#{name}@#{version}"
|
27
28
|
vulnerability = json[:advisory][:criticality] || Enum::VulnerabilityType::UNKNOWN
|
28
|
-
@vuln_hash[full_name] = Package.new(name, version) unless @vuln_hash.key? full_name
|
29
|
+
@vuln_hash[full_name] = Package.new(name, version, 'ruby') unless @vuln_hash.key? full_name
|
29
30
|
@vuln_hash[full_name].update vulnerabilities: @vuln_hash[full_name].vulnerabilities + [vulnerability]
|
30
31
|
end
|
31
32
|
end
|