package-audit 0.2.0 → 0.3.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 +22 -22
- data/lib/package/audit/command_service.rb +6 -6
- data/lib/package/audit/const/cmd.rb +3 -3
- 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/npm/node_collection.rb +5 -5
- data/lib/package/audit/npm/vulnerability_finder.rb +3 -2
- data/lib/package/audit/npm/yarn_lock_parser.rb +9 -5
- data/lib/package/audit/package.rb +5 -5
- data/lib/package/audit/printer.rb +5 -5
- data/lib/package/audit/risk_calculator.rb +1 -1
- data/lib/package/audit/ruby/bundler_specs.rb +15 -8
- data/lib/package/audit/ruby/gem_collection.rb +15 -11
- data/lib/package/audit/ruby/vulnerability_finder.rb +3 -2
- data/lib/package/audit/util/summary_printer.rb +2 -2
- data/lib/package/audit/version.rb +1 -1
- data/sig/package/audit/npm/vulnerability_finder.rbs +2 -1
- 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 +8 -4
- data/sig/package/audit/ruby/vulnerability_finder.rbs +3 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b01c3c377fec4245b836119f812bbacc6ceac724ed3c64da348f0b97481fd2a1
|
4
|
+
data.tar.gz: ceec2dc5e451fbe9ece1b915e35f790ed2ef60efb18fb3130ccc876e1eb7237c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0438ecb657dcaf116dc0048b89a9de474785d88e868f68f306521e917045651b525f49c8a6b802fda8401e8ff795f02b79c0be627fd337dc5eff4dcd48eaf128'
|
7
|
+
data.tar.gz: 38f68c6e7251196f2a526d4affcbb1487760615dd6947a3bd11b20f6ed0f791bac762a1327741b7c31e72ffa6a6b44471fdcfa98c0e0135d5d77b1751729ce80
|
data/lib/package/audit/cli.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative '
|
3
|
-
require_relative '
|
4
|
-
require_relative '
|
5
|
-
require_relative '
|
6
|
-
require_relative '
|
7
|
-
require_relative '
|
8
|
-
require_relative '
|
1
|
+
require_relative 'const/time'
|
2
|
+
require_relative 'version'
|
3
|
+
require_relative 'util/summary_printer'
|
4
|
+
require_relative 'ruby/bundler_specs'
|
5
|
+
require_relative 'printer'
|
6
|
+
require_relative 'ruby/gem_collection'
|
7
|
+
require_relative 'npm/node_collection'
|
8
|
+
require_relative 'command_service'
|
9
9
|
|
10
10
|
require 'json'
|
11
11
|
require 'thor'
|
@@ -17,44 +17,44 @@ module Package
|
|
17
17
|
|
18
18
|
map '--version' => :version
|
19
19
|
|
20
|
-
desc 'report', 'Show a report of potentially deprecated, outdated or vulnerable packages'
|
20
|
+
desc 'report [DIR]', 'Show a report of potentially deprecated, outdated or vulnerable packages'
|
21
21
|
method_option :csv, type: :boolean, default: false, desc: 'Output using comma separated values (CSV)'
|
22
22
|
method_option :'exclude-headers', type: :boolean, default: false, desc: 'Hide headers if when using CSV'
|
23
23
|
|
24
|
-
def report
|
25
|
-
within_rescue_block do
|
26
|
-
|
27
|
-
end
|
24
|
+
def report(dir = Dir.pwd)
|
25
|
+
# within_rescue_block do
|
26
|
+
exit CommandService.new(dir, options).all
|
27
|
+
# end
|
28
28
|
end
|
29
29
|
|
30
|
-
desc 'deprecated',
|
30
|
+
desc 'deprecated [DIR]',
|
31
31
|
"Show packages with no updates by author for at least #{Const::Time::YEARS_ELAPSED_TO_BE_OUTDATED} years"
|
32
32
|
method_option :csv, type: :boolean, default: false, desc: 'Output using comma separated values (CSV)'
|
33
33
|
method_option :'exclude-headers', type: :boolean, default: false, desc: 'Hide headers if when using CSV'
|
34
34
|
|
35
|
-
def deprecated
|
35
|
+
def deprecated(dir = Dir.pwd)
|
36
36
|
within_rescue_block do
|
37
|
-
exit CommandService.new(
|
37
|
+
exit CommandService.new(dir, options).deprecated
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
41
|
-
desc 'outdated', 'Show packages that are out of date'
|
41
|
+
desc 'outdated [DIR]', 'Show packages that are out of date'
|
42
42
|
method_option :csv, type: :boolean, default: false, desc: 'Output using comma separated values (CSV)'
|
43
43
|
method_option :'exclude-headers', type: :boolean, default: false, desc: 'Hide headers if when using CSV'
|
44
44
|
|
45
|
-
def outdated
|
45
|
+
def outdated(dir = Dir.pwd)
|
46
46
|
within_rescue_block do
|
47
|
-
exit CommandService.new(
|
47
|
+
exit CommandService.new(dir, options).outdated
|
48
48
|
end
|
49
49
|
end
|
50
50
|
|
51
|
-
desc 'vulnerable', 'Show packages and their dependencies that have security vulnerabilities'
|
51
|
+
desc 'vulnerable [DIR]', 'Show packages and their dependencies that have security vulnerabilities'
|
52
52
|
method_option :csv, type: :boolean, default: false, desc: 'Output using comma separated values (CSV)'
|
53
53
|
method_option :'exclude-headers', type: :boolean, default: false, desc: 'Hide headers if when using CSV'
|
54
54
|
|
55
|
-
def vulnerable
|
55
|
+
def vulnerable(dir = Dir.pwd)
|
56
56
|
within_rescue_block do
|
57
|
-
exit CommandService.new(
|
57
|
+
exit CommandService.new(dir, options).vulnerable
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
@@ -1,5 +1,5 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative '
|
1
|
+
require_relative 'const/cmd'
|
2
|
+
require_relative 'const/file'
|
3
3
|
|
4
4
|
module Package
|
5
5
|
module Audit
|
@@ -16,7 +16,7 @@ module Package
|
|
16
16
|
pkgs = []
|
17
17
|
|
18
18
|
if ruby?
|
19
|
-
gems = Ruby::GemCollection.all
|
19
|
+
gems = Ruby::GemCollection.new(@dir).all
|
20
20
|
pkgs += gems
|
21
21
|
Printer.new(gems, @options).print(Const::Fields::REPORT)
|
22
22
|
|
@@ -52,7 +52,7 @@ module Package
|
|
52
52
|
pkgs = []
|
53
53
|
|
54
54
|
if ruby?
|
55
|
-
gems = Ruby::GemCollection.vulnerable
|
55
|
+
gems = Ruby::GemCollection.new(@dir).vulnerable
|
56
56
|
pkgs += gems
|
57
57
|
Printer.new(gems, @options).print(Const::Fields::VULNERABLE)
|
58
58
|
|
@@ -88,7 +88,7 @@ module Package
|
|
88
88
|
pkgs = []
|
89
89
|
|
90
90
|
if ruby?
|
91
|
-
gems = Ruby::GemCollection.outdated
|
91
|
+
gems = Ruby::GemCollection.new(@dir).outdated
|
92
92
|
pkgs += gems
|
93
93
|
Printer.new(gems, @options).print(Const::Fields::OUTDATED)
|
94
94
|
|
@@ -122,7 +122,7 @@ module Package
|
|
122
122
|
pkgs = []
|
123
123
|
|
124
124
|
if ruby?
|
125
|
-
gems = Ruby::GemCollection.deprecated
|
125
|
+
gems = Ruby::GemCollection.new(@dir).deprecated
|
126
126
|
pkgs += gems
|
127
127
|
Printer.new(gems, @options).print(Const::Fields::OUTDATED)
|
128
128
|
|
@@ -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
|
@@ -1,6 +1,6 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative '
|
3
|
-
require_relative '
|
1
|
+
require_relative 'yarn_lock_parser'
|
2
|
+
require_relative 'npm_meta_data'
|
3
|
+
require_relative 'vulnerability_finder'
|
4
4
|
require_relative '../duplicate_package_merger'
|
5
5
|
|
6
6
|
module Package
|
@@ -17,7 +17,7 @@ module Package
|
|
17
17
|
|
18
18
|
def all
|
19
19
|
implicit_pkgs = fetch_from_lock_file
|
20
|
-
vulnerable_pkgs = VulnerabilityFinder.new(implicit_pkgs).run
|
20
|
+
vulnerable_pkgs = VulnerabilityFinder.new(@dir, implicit_pkgs).run
|
21
21
|
pkgs = NpmMetaData.new(vulnerable_pkgs + implicit_pkgs).fetch.filter(&:risk?)
|
22
22
|
DuplicatePackageMerger.new(pkgs).run
|
23
23
|
end
|
@@ -36,7 +36,7 @@ module Package
|
|
36
36
|
|
37
37
|
def vulnerable
|
38
38
|
implicit_pkgs = fetch_from_lock_file
|
39
|
-
vulnerable_pkgs = VulnerabilityFinder.new(implicit_pkgs).run
|
39
|
+
vulnerable_pkgs = VulnerabilityFinder.new(@dir, implicit_pkgs).run
|
40
40
|
pkgs = NpmMetaData.new(vulnerable_pkgs).fetch
|
41
41
|
DuplicatePackageMerger.new(pkgs).run
|
42
42
|
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)
|
@@ -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)
|
@@ -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,8 +1,8 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative '
|
3
|
-
require_relative '
|
4
|
-
require_relative '
|
5
|
-
require_relative '
|
1
|
+
require_relative 'risk'
|
2
|
+
require_relative 'risk_calculator'
|
3
|
+
require_relative 'enum/environment'
|
4
|
+
require_relative 'enum/risk_type'
|
5
|
+
require_relative 'enum/risk_explanation'
|
6
6
|
|
7
7
|
module Package
|
8
8
|
module Audit
|
@@ -1,8 +1,8 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative '
|
3
|
-
require_relative '
|
4
|
-
require_relative '
|
5
|
-
require_relative '
|
1
|
+
require_relative 'const/fields'
|
2
|
+
require_relative 'formatter/risk'
|
3
|
+
require_relative 'formatter/version'
|
4
|
+
require_relative 'formatter/version_date'
|
5
|
+
require_relative 'formatter/vulnerability'
|
6
6
|
|
7
7
|
module Package
|
8
8
|
module Audit
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require_relative '../package'
|
2
|
-
require_relative '
|
3
|
-
require_relative '
|
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,39 @@
|
|
1
|
-
require_relative '
|
2
|
-
require_relative '
|
1
|
+
require_relative 'bundler_specs'
|
2
|
+
require_relative '../enum/risk_type'
|
3
3
|
require_relative '../duplicate_package_merger'
|
4
4
|
|
5
5
|
module Package
|
6
6
|
module Audit
|
7
7
|
module Ruby
|
8
8
|
class GemCollection
|
9
|
-
def
|
10
|
-
|
9
|
+
def initialize(dir)
|
10
|
+
@dir = dir
|
11
|
+
end
|
12
|
+
|
13
|
+
def all
|
14
|
+
specs = BundlerSpecs.gemfile(@dir)
|
11
15
|
pkgs = specs.map { |spec| Package.new(spec.name, spec.version) }
|
12
|
-
vulnerable_pkgs = VulnerabilityFinder.new.run
|
16
|
+
vulnerable_pkgs = VulnerabilityFinder.new(@dir).run
|
13
17
|
pkgs = GemMetaData.new(pkgs + vulnerable_pkgs).fetch.filter(&:risk?)
|
14
18
|
DuplicatePackageMerger.new(pkgs).run
|
15
19
|
end
|
16
20
|
|
17
|
-
def
|
18
|
-
specs = BundlerSpecs.gemfile
|
21
|
+
def deprecated
|
22
|
+
specs = BundlerSpecs.gemfile(@dir)
|
19
23
|
pkgs = specs.map { |spec| Package.new(spec.name, spec.version) }
|
20
24
|
pkgs = GemMetaData.new(pkgs).fetch.filter(&:deprecated?)
|
21
25
|
DuplicatePackageMerger.new(pkgs).run
|
22
26
|
end
|
23
27
|
|
24
|
-
def
|
25
|
-
specs = include_implicit ? BundlerSpecs.all : BundlerSpecs.gemfile
|
28
|
+
def outdated(include_implicit: false)
|
29
|
+
specs = include_implicit ? BundlerSpecs.all(@dir) : BundlerSpecs.gemfile(@dir)
|
26
30
|
pkgs = specs.map { |spec| Package.new(spec.name, spec.version) }
|
27
31
|
pkgs = GemMetaData.new(pkgs).fetch.filter(&:outdated?)
|
28
32
|
DuplicatePackageMerger.new(pkgs).run
|
29
33
|
end
|
30
34
|
|
31
|
-
def
|
32
|
-
pkgs = VulnerabilityFinder.new.run
|
35
|
+
def vulnerable
|
36
|
+
pkgs = VulnerabilityFinder.new(@dir).run
|
33
37
|
pkgs = GemMetaData.new(pkgs).fetch.filter(&:vulnerable?)
|
34
38
|
DuplicatePackageMerger.new(pkgs).run
|
35
39
|
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)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require_relative '../const/time'
|
2
|
-
require_relative '
|
2
|
+
require_relative 'bash_color'
|
3
3
|
|
4
4
|
module Package
|
5
5
|
module Audit
|
@@ -8,7 +8,7 @@ module Package
|
|
8
8
|
def self.report
|
9
9
|
printf("\n%<info>s\n%<cmd>s\n\n",
|
10
10
|
info: Util::BashColor.blue('To show how risk is calculated run:'),
|
11
|
-
cmd: Util::BashColor.magenta(' >
|
11
|
+
cmd: Util::BashColor.magenta(' > package-audit risk'))
|
12
12
|
end
|
13
13
|
|
14
14
|
def self.deprecated
|
@@ -4,10 +4,11 @@ module Package
|
|
4
4
|
class VulnerabilityFinder
|
5
5
|
AUDIT_ADVISORY_REGEX: Regexp
|
6
6
|
|
7
|
+
@dir: String
|
7
8
|
@pkg_hash: Hash[String, Package]
|
8
9
|
@vuln_hash: Hash[String?, Package]
|
9
10
|
|
10
|
-
def initialize: (Array[Package]) -> void
|
11
|
+
def initialize: (String, Array[Package]) -> void
|
11
12
|
|
12
13
|
def run: -> Array[Package]
|
13
14
|
|
@@ -2,13 +2,17 @@ module Package
|
|
2
2
|
module Audit
|
3
3
|
module Ruby
|
4
4
|
class GemCollection
|
5
|
-
|
5
|
+
@dir: String
|
6
6
|
|
7
|
-
def
|
7
|
+
def initialize: (String) -> void
|
8
8
|
|
9
|
-
def
|
9
|
+
def all: -> Array[Package]
|
10
10
|
|
11
|
-
def
|
11
|
+
def deprecated: -> Array[Package]
|
12
|
+
|
13
|
+
def outdated: (?include_implicit: bool) -> Array[Package]
|
14
|
+
|
15
|
+
def vulnerable: -> Array[Package]
|
12
16
|
end
|
13
17
|
end
|
14
18
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: package-audit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Vadim Kononov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-05
|
11
|
+
date: 2023-07-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler-audit
|