bundler-audit 0.8.0.rc1 → 0.8.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +3 -0
- data/.github/workflows/ruby.yml +2 -1
- data/ChangeLog.md +14 -10
- data/README.md +1 -1
- data/gemspec.yml +1 -1
- data/lib/bundler/audit/cli.rb +8 -13
- data/lib/bundler/audit/cli/formats/text.rb +7 -5
- data/lib/bundler/audit/cli/thor_ext/shell/basic/say_error.rb +33 -0
- data/lib/bundler/audit/configuration.rb +4 -0
- data/lib/bundler/audit/version.rb +1 -1
- data/spec/cli/formats/text_spec.rb +26 -2
- data/spec/cli_spec.rb +5 -5
- data/spec/configuration_spec.rb +8 -0
- data/spec/fixtures/advisory/CVE-2020-1234.yml +1 -0
- data/spec/fixtures/config/bad/empty.yml +0 -0
- data/spec/integration_spec.rb +17 -103
- metadata +9 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d68852584664d93222c7f24f8d7d2f42038e32addf0b79953e4f9ea41c4a803
|
4
|
+
data.tar.gz: 929bf4dcf07474ce2222d119377e34630572ca68c1d821ff48056d006c6a731c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27f710fb3917beda059a73b41729a1c9ab0d2c4b7472b7ede77c2bbfbd1085deb9cb09eb154c7e4a5a1f41f516f50a27f79110e534d943f56170633c9e2338cc
|
7
|
+
data.tar.gz: 48800f8b91c823b69606b38a172a58ff37a2ad64ead80f087da80efcd6cbd0991cc716cbbaa9efc3925690f9da47c750e9c218624aa0b02fad209b6b092aab7b
|
data/.github/FUNDING.yml
ADDED
data/.github/workflows/ruby.yml
CHANGED
data/ChangeLog.md
CHANGED
@@ -37,14 +37,15 @@
|
|
37
37
|
|
38
38
|
#### CLI
|
39
39
|
|
40
|
-
*
|
41
|
-
* Added `
|
42
|
-
* `
|
40
|
+
* Require [thor] ~> 1.0.
|
41
|
+
* Added `bundler-audit stats`.
|
42
|
+
* Added `bundler-audit download`.
|
43
|
+
* `bundler-audit check`:
|
43
44
|
* Now accepts a optional `DIR` argument for the project directory.
|
44
|
-
* `
|
45
|
+
* `bundler-audit check` will now print an explicit error message and exit,
|
45
46
|
if the given `DIR` does not exist.
|
46
|
-
* Will now auto-download
|
47
|
-
|
47
|
+
* Will now auto-download [ruby-advisory-db] to ensure the latest advisory
|
48
|
+
information is used on first run.
|
48
49
|
* Now supports a `--database` option for specifying a path
|
49
50
|
to an alternative [ruby-advisory-db] copy.
|
50
51
|
* Now supports a `--gemfile-lock` option for specifying a
|
@@ -53,6 +54,9 @@
|
|
53
54
|
desired format. `text` and `json` are supported, but other custom formats
|
54
55
|
can be loaded. See {Bundler::Audit::CLI::Formats}.
|
55
56
|
* Now supports a `--output` option for writing the report output to a file.
|
57
|
+
* Prints both CVE and GHSA IDs.
|
58
|
+
* Print all error messages to stderr.
|
59
|
+
* No longer print number of advisories in `bundler-audit version`.
|
56
60
|
|
57
61
|
### 0.7.0.1 / 2020-06-12
|
58
62
|
|
@@ -91,9 +95,9 @@
|
|
91
95
|
|
92
96
|
#### CLI
|
93
97
|
|
94
|
-
* Added the `--update` option to `
|
95
|
-
* `
|
96
|
-
* `
|
98
|
+
* Added the `--update` option to `bundler-audit check`.
|
99
|
+
* `bundler-audit update` now returns a non-zero exit status on error.
|
100
|
+
* `bundler-audit update` only updates `~/.local/share/ruby-advisory-db`, if it is a git
|
97
101
|
repository.
|
98
102
|
|
99
103
|
### 0.4.0 / 2015-06-30
|
@@ -131,7 +135,7 @@
|
|
131
135
|
|
132
136
|
#### CLI
|
133
137
|
|
134
|
-
* Added the `
|
138
|
+
* Added the `bundler-audit update` sub-command.
|
135
139
|
|
136
140
|
### 0.2.0 / 2013-03-05
|
137
141
|
|
data/README.md
CHANGED
data/gemspec.yml
CHANGED
data/lib/bundler/audit/cli.rb
CHANGED
@@ -20,6 +20,7 @@ require 'bundler/audit/version'
|
|
20
20
|
require 'bundler/audit/cli/formats'
|
21
21
|
|
22
22
|
require 'thor'
|
23
|
+
require 'bundler/audit/cli/thor_ext/shell/basic/say_error'
|
23
24
|
require 'bundler'
|
24
25
|
|
25
26
|
module Bundler
|
@@ -42,18 +43,18 @@ module Bundler
|
|
42
43
|
|
43
44
|
def check(dir=Dir.pwd)
|
44
45
|
unless File.directory?(dir)
|
45
|
-
|
46
|
+
say_error "No such file or directory: #{dir}", :red
|
46
47
|
exit 1
|
47
48
|
end
|
48
49
|
|
49
50
|
begin
|
50
51
|
extend Formats.load(options[:format])
|
51
52
|
rescue Formats::FormatNotFound
|
52
|
-
|
53
|
+
say_error "Unknown format: #{options[:format]}", :red
|
53
54
|
exit 1
|
54
55
|
end
|
55
56
|
|
56
|
-
if !Database.exists?
|
57
|
+
if !Database.exists?(options[:database])
|
57
58
|
download(options[:database])
|
58
59
|
elsif options[:update]
|
59
60
|
update(options[:database])
|
@@ -128,13 +129,14 @@ module Bundler
|
|
128
129
|
when true
|
129
130
|
say("Updated ruby-advisory-db", :green) unless options.quiet?
|
130
131
|
when false
|
131
|
-
|
132
|
+
say_error "Failed updating ruby-advisory-db!", :red
|
132
133
|
exit 1
|
133
134
|
when nil
|
134
135
|
unless Bundler.git_present?
|
135
|
-
|
136
|
+
say_error "Git is not installed!", :red
|
136
137
|
exit 1
|
137
138
|
end
|
139
|
+
|
138
140
|
say "Skipping update", :yellow
|
139
141
|
end
|
140
142
|
|
@@ -143,9 +145,7 @@ module Bundler
|
|
143
145
|
|
144
146
|
desc 'version', 'Prints the bundler-audit version'
|
145
147
|
def version
|
146
|
-
|
147
|
-
|
148
|
-
puts "#{File.basename($0)} #{VERSION} (advisories: #{database.size})"
|
148
|
+
puts "bundler-audit #{VERSION}"
|
149
149
|
end
|
150
150
|
|
151
151
|
protected
|
@@ -157,11 +157,6 @@ module Bundler
|
|
157
157
|
raise(NotImplementedError,"#{self.class}##{__method__} not defined")
|
158
158
|
end
|
159
159
|
|
160
|
-
def say(message="", color=nil)
|
161
|
-
color = nil unless $stdout.tty?
|
162
|
-
super(message.to_s, color)
|
163
|
-
end
|
164
|
-
|
165
160
|
end
|
166
161
|
end
|
167
162
|
end
|
@@ -66,12 +66,14 @@ module Bundler
|
|
66
66
|
say "Version: ", :red
|
67
67
|
say gem.version
|
68
68
|
|
69
|
-
say "Advisory: ", :red
|
70
|
-
|
71
69
|
if advisory.cve
|
72
|
-
say "CVE
|
73
|
-
|
74
|
-
|
70
|
+
say "CVE: ", :red
|
71
|
+
say advisory.cve_id
|
72
|
+
end
|
73
|
+
|
74
|
+
if advisory.ghsa
|
75
|
+
say "GHSA: ", :red
|
76
|
+
say advisory.ghsa_id
|
75
77
|
end
|
76
78
|
|
77
79
|
say "Criticality: ", :red
|
@@ -0,0 +1,33 @@
|
|
1
|
+
class Thor
|
2
|
+
module Shell
|
3
|
+
class Basic
|
4
|
+
#
|
5
|
+
# Prints an error message to `stderr`.
|
6
|
+
#
|
7
|
+
# @param [String] message
|
8
|
+
# The message to print to `stderr`.
|
9
|
+
#
|
10
|
+
# @param [Symbol, nil] color
|
11
|
+
# Optional ANSI color.
|
12
|
+
#
|
13
|
+
# @param [Boolean] force_new_line
|
14
|
+
# Controls whether a newline character will be appended to the output.
|
15
|
+
#
|
16
|
+
def say_error(message,color=nil,force_new_line=(message.to_s !~ /( |\t)\Z/))
|
17
|
+
return if quiet?
|
18
|
+
|
19
|
+
buffer = prepare_message(message,*color)
|
20
|
+
buffer << $/ if force_new_line && !message.to_s.end_with?($/)
|
21
|
+
|
22
|
+
stderr.print(buffer)
|
23
|
+
stderr.flush
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module_eval <<-METHOD, __FILE__, __LINE__ + 1
|
28
|
+
def say_error(*args,&block)
|
29
|
+
shell.say_error(*args,&block)
|
30
|
+
end
|
31
|
+
METHOD
|
32
|
+
end
|
33
|
+
end
|
@@ -52,6 +52,10 @@ module Bundler
|
|
52
52
|
|
53
53
|
doc = YAML.parse(File.new(file_path))
|
54
54
|
|
55
|
+
unless doc.kind_of?(YAML::Nodes::Document)
|
56
|
+
raise(InvalidConfigurationError,"Configuration found in '#{file_path}' is not YAML")
|
57
|
+
end
|
58
|
+
|
55
59
|
unless doc.root.kind_of?(YAML::Nodes::Mapping)
|
56
60
|
raise(InvalidConfigurationError,"Configuration found in '#{file_path}' is not a Hash")
|
57
61
|
end
|
@@ -76,8 +76,32 @@ describe Bundler::Audit::CLI::Formats::Text do
|
|
76
76
|
expect(output_lines).to include("Version: #{gem.version}")
|
77
77
|
end
|
78
78
|
|
79
|
-
|
80
|
-
|
79
|
+
context "when the advisory has a CVE ID" do
|
80
|
+
it "must print 'CVE: CVE-YYYY-NNNN'" do
|
81
|
+
expect(output_lines).to include("CVE: CVE-#{advisory.cve}")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
context "when the advisory does not have a CVE ID" do
|
86
|
+
before { advisory.cve = nil }
|
87
|
+
|
88
|
+
it "must not print 'CVE: CVE-YYYY-NNNN'" do
|
89
|
+
expect(output_lines).to_not include("CVE: CVE-#{advisory.cve}")
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context "when the advisory has a GHSA ID" do
|
94
|
+
it "must print 'GHSA: GHSA-xxxx-xxxx-xxxx'" do
|
95
|
+
expect(output_lines).to include("GHSA: GHSA-#{advisory.ghsa}")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context "when the advisory does not have a GHSA ID" do
|
100
|
+
before { advisory.ghsa = nil }
|
101
|
+
|
102
|
+
it "must not print 'GHSA: GHSA-xxxx-xxxx-xxxx'" do
|
103
|
+
expect(output_lines).to_not include("GHSA: GHSA-#{advisory.ghsa}")
|
104
|
+
end
|
81
105
|
end
|
82
106
|
|
83
107
|
context "when Advisory#criticality is :low" do
|
data/spec/cli_spec.rb
CHANGED
@@ -45,7 +45,7 @@ describe Bundler::Audit::CLI do
|
|
45
45
|
subject.update
|
46
46
|
rescue SystemExit
|
47
47
|
end
|
48
|
-
}.to output(/Failed updating ruby-advisory-db!/).
|
48
|
+
}.to output(/Failed updating ruby-advisory-db!/).to_stderr
|
49
49
|
end
|
50
50
|
|
51
51
|
it "exits with error status code" do
|
@@ -73,7 +73,7 @@ describe Bundler::Audit::CLI do
|
|
73
73
|
subject.update
|
74
74
|
rescue SystemExit
|
75
75
|
end
|
76
|
-
end.to output(/Git is not installed!/).
|
76
|
+
end.to output(/Git is not installed!/).to_stderr
|
77
77
|
end
|
78
78
|
|
79
79
|
it "exits with error status code" do
|
@@ -90,8 +90,8 @@ describe Bundler::Audit::CLI do
|
|
90
90
|
end
|
91
91
|
|
92
92
|
context "--quiet" do
|
93
|
-
|
94
|
-
|
93
|
+
subject do
|
94
|
+
described_class.new([], {quiet: true})
|
95
95
|
end
|
96
96
|
|
97
97
|
context "when update succeeds" do
|
@@ -119,7 +119,7 @@ describe Bundler::Audit::CLI do
|
|
119
119
|
subject.update
|
120
120
|
rescue SystemExit
|
121
121
|
end
|
122
|
-
}.
|
122
|
+
}.to_not output.to_stderr
|
123
123
|
end
|
124
124
|
|
125
125
|
it "exits with error status code" do
|
data/spec/configuration_spec.rb
CHANGED
@@ -22,6 +22,14 @@ describe Bundler::Audit::Configuration do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
context "validations" do
|
25
|
+
context "when the file is empty" do
|
26
|
+
let(:path) { File.join(fixtures_dir,'bad','empty.yml') }
|
27
|
+
|
28
|
+
it 'raises a validation error' do
|
29
|
+
expect { subject }.to raise_error(described_class::InvalidConfigurationError)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
25
33
|
context "when ignore is not an array" do
|
26
34
|
let(:path) { File.join(fixtures_dir,'bad','ignore_is_not_an_array.yml') }
|
27
35
|
|
File without changes
|
data/spec/integration_spec.rb
CHANGED
@@ -1,117 +1,31 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe "
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
File.expand_path(File.join(File.dirname(__FILE__),'..','bin','bundler-audit'))
|
8
|
-
end
|
9
|
-
|
10
|
-
context "when auditing a bundle with unpatched gems" do
|
11
|
-
let(:bundle) { 'unpatched_gems' }
|
12
|
-
let(:directory) { File.join('spec','bundle',bundle) }
|
13
|
-
|
14
|
-
subject do
|
15
|
-
Dir.chdir(directory) { sh(command, :fail => true) }
|
16
|
-
end
|
17
|
-
|
18
|
-
it "should print a warning" do
|
19
|
-
expect(subject).to include("Vulnerabilities found!")
|
20
|
-
end
|
21
|
-
|
22
|
-
it "should print advisory information for the vulnerable gems" do
|
23
|
-
advisory_pattern = %r{(Name: [^\n]+
|
24
|
-
Version: \d+\.\d+\.\d+(\.\d+)?
|
25
|
-
Advisory: CVE-[0-9]{4}-[0-9]{4}
|
26
|
-
Criticality: (Critical|High|Medium|Low|None|Unknown)
|
27
|
-
URL: https?://(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#!?&//=]*)
|
28
|
-
Title: [^\n]*?
|
29
|
-
Solution: upgrade to (~>|>=) \d+\.\d+\.\d+(\.\d+)?(, (~>|>=) \d+\.\d+\.\d+(\.\d+)?)*[\s\n]*?)}
|
30
|
-
|
31
|
-
expect(subject).to match(advisory_pattern)
|
32
|
-
expect(subject).to include("Vulnerabilities found!")
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
context "when auditing a bundle with ignored gems" do
|
37
|
-
let(:bundle) { 'unpatched_gems' }
|
38
|
-
let(:directory) { File.join('spec','bundle',bundle) }
|
39
|
-
|
40
|
-
let(:command) do
|
41
|
-
File.expand_path(File.join(File.dirname(__FILE__),'..','bin','bundler-audit -i CVE-2013-0156'))
|
42
|
-
end
|
43
|
-
|
44
|
-
subject do
|
45
|
-
Dir.chdir(directory) { sh(command, :fail => true) }
|
46
|
-
end
|
47
|
-
|
48
|
-
it "should not print advisory information for ignored gem" do
|
49
|
-
expect(subject).not_to include("CVE-2013-0156")
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
context "when auditing a bundle with insecure sources" do
|
54
|
-
let(:bundle) { 'insecure_sources' }
|
55
|
-
let(:directory) { File.join('spec','bundle',bundle) }
|
56
|
-
|
57
|
-
subject do
|
58
|
-
Dir.chdir(directory) { sh(command, :fail => true) }
|
59
|
-
end
|
60
|
-
|
61
|
-
it "should print warnings about insecure sources" do
|
62
|
-
expect(subject).to include(%{
|
63
|
-
Insecure Source URI found: git://github.com/rails/jquery-rails.git
|
64
|
-
Insecure Source URI found: http://rubygems.org/
|
65
|
-
}.strip)
|
66
|
-
end
|
3
|
+
describe "bin/bundler-audit" do
|
4
|
+
let(:name) { 'bundler-audit' }
|
5
|
+
let(:path) do
|
6
|
+
File.expand_path(File.join(File.dirname(__FILE__),'..','bin',name))
|
67
7
|
end
|
68
8
|
|
69
|
-
|
70
|
-
let(:bundle) { 'secure' }
|
71
|
-
let(:directory) { File.join('spec','bundle',bundle) }
|
9
|
+
let(:command) { "#{path} version" }
|
72
10
|
|
73
|
-
|
74
|
-
Dir.chdir(directory) { sh(command) }
|
75
|
-
end
|
11
|
+
subject { sh(command) }
|
76
12
|
|
77
|
-
|
78
|
-
|
79
|
-
end
|
13
|
+
it "must invoke the CLI class" do
|
14
|
+
expect(subject).to eq("bundler-audit #{Bundler::Audit::VERSION}#{$/}")
|
80
15
|
end
|
16
|
+
end
|
81
17
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
let(:gemfile_lock) { 'Gemfile.foo.lock' }
|
88
|
-
let(:command) { "#{super()} --gemfile-lock #{gemfile_lock}" }
|
89
|
-
|
90
|
-
subject do
|
91
|
-
Dir.chdir(directory) { sh(command, :fail => true) }
|
92
|
-
end
|
93
|
-
|
94
|
-
it "should print an error message" do
|
95
|
-
expect(subject.strip).to eq("Could not find #{gemfile_lock.inspect} in #{root.inspect}")
|
96
|
-
end
|
18
|
+
describe "bin/bundle-audit" do
|
19
|
+
let(:name) { 'bundle-audit' }
|
20
|
+
let(:path) do
|
21
|
+
File.expand_path(File.join(File.dirname(__FILE__),'..','bin',name))
|
97
22
|
end
|
98
23
|
|
99
|
-
|
100
|
-
let(:update_command) { "#{command} update" }
|
101
|
-
let(:bundle) { 'secure' }
|
102
|
-
let(:directory) { File.join('spec','bundle',bundle) }
|
24
|
+
let(:command) { "#{path} version" }
|
103
25
|
|
104
|
-
|
105
|
-
Dir.chdir(directory) { sh(update_command) }
|
106
|
-
end
|
26
|
+
subject { sh(command) }
|
107
27
|
|
108
|
-
|
109
|
-
|
110
|
-
expect(subject).not_to include("Fail")
|
111
|
-
expect(subject).to include("Updating ruby-advisory-db ...\n")
|
112
|
-
expect(subject).to include("Updated ruby-advisory-db\n")
|
113
|
-
expect(subject).to match(/ruby-advisory-db:\n advisories:\s+[1-9]\d+ advisories/)
|
114
|
-
end
|
115
|
-
end
|
28
|
+
it "must invoke the CLI class" do
|
29
|
+
expect(subject).to eq("bundler-audit #{Bundler::Audit::VERSION}#{$/}")
|
116
30
|
end
|
117
31
|
end
|
metadata
CHANGED
@@ -1,35 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bundler-audit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.0.
|
4
|
+
version: 0.8.0.rc2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Postmodern
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-02-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '0.18'
|
20
|
-
- - "<"
|
17
|
+
- - "~>"
|
21
18
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
19
|
+
version: '1.0'
|
23
20
|
type: :runtime
|
24
21
|
prerelease: false
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
|
-
- - "
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '0.18'
|
30
|
-
- - "<"
|
24
|
+
- - "~>"
|
31
25
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
26
|
+
version: '1.0'
|
33
27
|
- !ruby/object:Gem::Dependency
|
34
28
|
name: bundler
|
35
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -62,6 +56,7 @@ extra_rdoc_files:
|
|
62
56
|
- README.md
|
63
57
|
files:
|
64
58
|
- ".document"
|
59
|
+
- ".github/FUNDING.yml"
|
65
60
|
- ".github/workflows/ruby.yml"
|
66
61
|
- ".gitignore"
|
67
62
|
- ".rspec"
|
@@ -81,6 +76,7 @@ files:
|
|
81
76
|
- lib/bundler/audit/cli/formats.rb
|
82
77
|
- lib/bundler/audit/cli/formats/json.rb
|
83
78
|
- lib/bundler/audit/cli/formats/text.rb
|
79
|
+
- lib/bundler/audit/cli/thor_ext/shell/basic/say_error.rb
|
84
80
|
- lib/bundler/audit/configuration.rb
|
85
81
|
- lib/bundler/audit/database.rb
|
86
82
|
- lib/bundler/audit/report.rb
|
@@ -110,6 +106,7 @@ files:
|
|
110
106
|
- spec/database_spec.rb
|
111
107
|
- spec/fixtures/advisory/CVE-2020-1234.yml
|
112
108
|
- spec/fixtures/advisory/not_a_hash.yml
|
109
|
+
- spec/fixtures/config/bad/empty.yml
|
113
110
|
- spec/fixtures/config/bad/ignore_contains_a_non_string.yml
|
114
111
|
- spec/fixtures/config/bad/ignore_is_not_an_array.yml
|
115
112
|
- spec/fixtures/config/valid.yml
|