bundler-audit 0.3.1 → 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/.gitignore +3 -0
- data/.travis.yml +5 -3
- data/ChangeLog.md +15 -0
- data/Gemfile +2 -1
- data/README.md +8 -1
- data/Rakefile +3 -13
- data/gemspec.yml +1 -0
- data/lib/bundler/audit.rb +1 -1
- data/lib/bundler/audit/advisory.rb +5 -1
- data/lib/bundler/audit/cli.rb +9 -4
- data/lib/bundler/audit/database.rb +2 -2
- data/lib/bundler/audit/scanner.rb +101 -3
- data/lib/bundler/audit/version.rb +2 -2
- data/spec/advisory_spec.rb +51 -25
- data/spec/audit_spec.rb +1 -1
- data/spec/bundle/insecure_sources/Gemfile +1 -1
- data/spec/bundle/secure/Gemfile +1 -1
- data/spec/bundle/unpatched_gems/Gemfile +1 -1
- data/spec/database_spec.rb +10 -10
- data/spec/integration_spec.rb +6 -6
- data/spec/scanner_spec.rb +8 -8
- data/spec/spec_helper.rb +7 -4
- metadata +33 -33
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9660b06fce10c2532f0c7aaa5fef6ca2d5c99067
|
4
|
+
data.tar.gz: 751d7e542727defa267b6d8abf2ad0b3f391ab70
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2a3cb90acc0cecc82ee931fedd43ab4d0439fd2436bc29563a45a4a328862c9038f243f7bff68a9e394bb0c12fee6f83b1496347187783b3a6d972435169dbf3
|
7
|
+
data.tar.gz: 89a771db86e3baf43430b5448bee5664e1b73f017fed9c48756ea8a58f6f4515c761d4c46333a93e9bcde71e3c6777271ec799a933d5662a76df9504a29dd09d
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/ChangeLog.md
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
### 0.4.0 / 2015-06-30
|
2
|
+
|
3
|
+
* Require ruby >= 1.9.3 due to i18n gem deprecating < 1.9.3.
|
4
|
+
* Added {Bundler::Audit::Advisory#osvdb}.
|
5
|
+
* Resolve the IP addresses of gem sources and ignore intranet gem sources.
|
6
|
+
(PR #90)
|
7
|
+
* Use ISO8601 date format when querying the git timestamp of ruby-advisory-db.
|
8
|
+
(PR #92)
|
9
|
+
|
10
|
+
#### CLI
|
11
|
+
|
12
|
+
* Print the CVE or OSVDB id.
|
13
|
+
* No longer print "Unpatched versions found!" when an insecure gem source
|
14
|
+
is detected. (PR #84)
|
15
|
+
|
1
16
|
### 0.3.1 / 2014-04-20
|
2
17
|
|
3
18
|
* Added thor ~> 0.18 as a dependency.
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -108,8 +108,13 @@ Update the [ruby-advisory-db] that `bundle-audit` uses:
|
|
108
108
|
create mode 100644 gems/wicked/OSVDB-98270.yml
|
109
109
|
ruby-advisory-db: 64 advisories
|
110
110
|
|
111
|
+
Ignore specific advisories:
|
112
|
+
|
113
|
+
$ bundle-audit check --ignore OSVDB-108664
|
114
|
+
|
111
115
|
## Requirements
|
112
116
|
|
117
|
+
* [Ruby] >= 1.9.3
|
113
118
|
* [RubyGems] >= 1.8
|
114
119
|
* [thor] ~> 0.18
|
115
120
|
* [bundler] ~> 1.2
|
@@ -120,7 +125,7 @@ Update the [ruby-advisory-db] that `bundle-audit` uses:
|
|
120
125
|
|
121
126
|
## License
|
122
127
|
|
123
|
-
Copyright (c) 2013-
|
128
|
+
Copyright (c) 2013-2015 Hal Brodigan (postmodern.mod3 at gmail.com)
|
124
129
|
|
125
130
|
bundler-audit is free software: you can redistribute it and/or modify
|
126
131
|
it under the terms of the GNU General Public License as published by
|
@@ -135,8 +140,10 @@ GNU General Public License for more details.
|
|
135
140
|
You should have received a copy of the GNU General Public License
|
136
141
|
along with bundler-audit. If not, see <http://www.gnu.org/licenses/>.
|
137
142
|
|
143
|
+
[Ruby]: https://ruby-lang.org
|
138
144
|
[RubyGems]: https://rubygems.org
|
139
145
|
[thor]: http://whatisthor.com/
|
140
146
|
[bundler]: https://github.com/carlhuda/bundler#readme
|
141
147
|
|
142
148
|
[OSVDB]: http://osvdb.org/
|
149
|
+
[ruby-advisory-db]: https://github.com/rubysec/ruby-advisory-db
|
data/Rakefile
CHANGED
@@ -3,19 +3,9 @@
|
|
3
3
|
require 'rubygems'
|
4
4
|
|
5
5
|
begin
|
6
|
-
require 'bundler'
|
6
|
+
require 'bundler/setup'
|
7
7
|
rescue LoadError => e
|
8
|
-
|
9
|
-
warn "Run `gem install bundler` to install Bundler."
|
10
|
-
exit -1
|
11
|
-
end
|
12
|
-
|
13
|
-
begin
|
14
|
-
Bundler.setup(:development)
|
15
|
-
rescue Bundler::BundlerError => e
|
16
|
-
warn e.message
|
17
|
-
warn "Run `bundle install` to install missing gems."
|
18
|
-
exit e.status_code
|
8
|
+
abort e.message
|
19
9
|
end
|
20
10
|
|
21
11
|
require 'rake'
|
@@ -52,7 +42,7 @@ namespace :spec do
|
|
52
42
|
|
53
43
|
%w[secure unpatched_gems insecure_sources].each do |bundle|
|
54
44
|
chdir(File.join(root,bundle)) do
|
55
|
-
sh 'BUNDLE_BIN_PATH
|
45
|
+
sh 'unset BUNDLE_BIN_PATH BUNDLE_GEMFILE RUBYOPT && bundle install --path ../../../vendor/bundle'
|
56
46
|
end
|
57
47
|
end
|
58
48
|
end
|
data/gemspec.yml
CHANGED
data/lib/bundler/audit.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright (c) 2013-
|
2
|
+
# Copyright (c) 2013-2015 Hal Brodigan (postmodern.mod3 at gmail.com)
|
3
3
|
#
|
4
4
|
# bundler-audit is free software: you can redistribute it and/or modify
|
5
5
|
# it under the terms of the GNU General Public License as published by
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright (c) 2013-
|
2
|
+
# Copyright (c) 2013-2015 Hal Brodigan (postmodern.mod3 at gmail.com)
|
3
3
|
#
|
4
4
|
# bundler-audit is free software: you can redistribute it and/or modify
|
5
5
|
# it under the terms of the GNU General Public License as published by
|
@@ -25,6 +25,8 @@ module Bundler
|
|
25
25
|
:title,
|
26
26
|
:description,
|
27
27
|
:cvss_v2,
|
28
|
+
:cve,
|
29
|
+
:osvdb,
|
28
30
|
:unaffected_versions,
|
29
31
|
:patched_versions)
|
30
32
|
|
@@ -59,6 +61,8 @@ module Bundler
|
|
59
61
|
data['title'],
|
60
62
|
data['description'],
|
61
63
|
data['cvss_v2'],
|
64
|
+
data['cve'],
|
65
|
+
data['osvdb'],
|
62
66
|
parse_versions[data['unaffected_versions']],
|
63
67
|
parse_versions[data['patched_versions']]
|
64
68
|
)
|
data/lib/bundler/audit/cli.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright (c) 2013-
|
2
|
+
# Copyright (c) 2013-2015 Hal Brodigan (postmodern.mod3 at gmail.com)
|
3
3
|
#
|
4
4
|
# bundler-audit is free software: you can redistribute it and/or modify
|
5
5
|
# it under the terms of the GNU General Public License as published by
|
@@ -49,10 +49,10 @@ module Bundler
|
|
49
49
|
end
|
50
50
|
|
51
51
|
if vulnerable
|
52
|
-
say "
|
52
|
+
say "Vulnerabilities found!", :red
|
53
53
|
exit 1
|
54
54
|
else
|
55
|
-
say "No
|
55
|
+
say "No vulnerabilities found", :green
|
56
56
|
end
|
57
57
|
end
|
58
58
|
|
@@ -90,7 +90,12 @@ module Bundler
|
|
90
90
|
say gem.version
|
91
91
|
|
92
92
|
say "Advisory: ", :red
|
93
|
-
|
93
|
+
|
94
|
+
if advisory.cve
|
95
|
+
say "CVE-#{advisory.cve}"
|
96
|
+
elsif advisory.osvdb
|
97
|
+
say advisory.osvdb
|
98
|
+
end
|
94
99
|
|
95
100
|
say "Criticality: ", :red
|
96
101
|
case advisory.criticality
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright (c) 2013-
|
2
|
+
# Copyright (c) 2013-2015 Hal Brodigan (postmodern.mod3 at gmail.com)
|
3
3
|
#
|
4
4
|
# bundler-audit is free software: you can redistribute it and/or modify
|
5
5
|
# it under the terms of the GNU General Public License as published by
|
@@ -68,7 +68,7 @@ module Bundler
|
|
68
68
|
#
|
69
69
|
def self.path
|
70
70
|
if File.directory?(USER_PATH)
|
71
|
-
t1 = Dir.chdir(USER_PATH) { Time.parse(`git log --pretty="%cd" -1`) }
|
71
|
+
t1 = Dir.chdir(USER_PATH) { Time.parse(`git log --date=iso8601 --pretty="%cd" -1`) }
|
72
72
|
t2 = VENDORED_TIMESTAMP
|
73
73
|
|
74
74
|
if t1 >= t2 then USER_PATH
|
@@ -2,7 +2,10 @@ require 'bundler'
|
|
2
2
|
require 'bundler/audit/database'
|
3
3
|
require 'bundler/lockfile_parser'
|
4
4
|
|
5
|
+
require 'ipaddr'
|
6
|
+
require 'resolv'
|
5
7
|
require 'set'
|
8
|
+
require 'uri'
|
6
9
|
|
7
10
|
module Bundler
|
8
11
|
module Audit
|
@@ -59,17 +62,46 @@ module Bundler
|
|
59
62
|
# @return [Enumerator]
|
60
63
|
# If no block is given, an Enumerator will be returned.
|
61
64
|
#
|
62
|
-
def scan(options={})
|
63
|
-
return enum_for(__method__,options) unless
|
65
|
+
def scan(options={},&block)
|
66
|
+
return enum_for(__method__,options) unless block
|
64
67
|
|
65
68
|
ignore = Set[]
|
66
69
|
ignore += options[:ignore] if options[:ignore]
|
67
70
|
|
71
|
+
scan_sources(options,&block)
|
72
|
+
scan_specs(options,&block)
|
73
|
+
|
74
|
+
return self
|
75
|
+
end
|
76
|
+
|
77
|
+
#
|
78
|
+
# Scans the gem sources in the lockfile.
|
79
|
+
#
|
80
|
+
# @param [Hash] options
|
81
|
+
# Additional options.
|
82
|
+
#
|
83
|
+
# @yield [result]
|
84
|
+
# The given block will be passed the results of the scan.
|
85
|
+
#
|
86
|
+
# @yieldparam [InsecureSource] result
|
87
|
+
# A result from the scan.
|
88
|
+
#
|
89
|
+
# @return [Enumerator]
|
90
|
+
# If no block is given, an Enumerator will be returned.
|
91
|
+
#
|
92
|
+
# @api semipublic
|
93
|
+
#
|
94
|
+
# @since 0.4.0
|
95
|
+
#
|
96
|
+
def scan_sources(options={})
|
97
|
+
return enum_for(__method__,options) unless block_given?
|
98
|
+
|
68
99
|
@lockfile.sources.map do |source|
|
69
100
|
case source
|
70
101
|
when Source::Git
|
71
102
|
case source.uri
|
72
103
|
when /^git:/, /^http:/
|
104
|
+
next if internal_host?(source.uri)
|
73
105
|
yield InsecureSource.new(source.uri)
|
74
106
|
end
|
75
107
|
when Source::Rubygems
|
@@ -80,6 +112,35 @@ module Bundler
|
|
80
112
|
end
|
81
113
|
end
|
82
114
|
end
|
115
|
+
end
|
116
|
+
|
117
|
+
#
|
118
|
+
# Scans the gem sources in the lockfile.
|
119
|
+
#
|
120
|
+
# @param [Hash] options
|
121
|
+
# Additional options.
|
122
|
+
#
|
123
|
+
# @option options [Array<String>] :ignore
|
124
|
+
# The advisories to ignore.
|
125
|
+
#
|
126
|
+
# @yield [result]
|
127
|
+
# The given block will be passed the results of the scan.
|
128
|
+
#
|
129
|
+
# @yieldparam [UnpatchedGem] result
|
130
|
+
# A result from the scan.
|
131
|
+
#
|
132
|
+
# @return [Enumerator]
|
133
|
+
# If no block is given, an Enumerator will be returned.
|
134
|
+
#
|
135
|
+
# @api semipublic
|
136
|
+
#
|
137
|
+
# @since 0.4.0
|
138
|
+
#
|
139
|
+
def scan_specs(options={})
|
140
|
+
return enum_for(__method__,options) unless block_given?
|
141
|
+
|
142
|
+
ignore = Set[]
|
143
|
+
ignore += options[:ignore] if options[:ignore]
|
83
144
|
|
84
145
|
@lockfile.specs.each do |gem|
|
85
146
|
@database.check_gem(gem) do |advisory|
|
@@ -88,10 +149,47 @@ module Bundler
|
|
88
149
|
end
|
89
150
|
end
|
90
151
|
end
|
152
|
+
end
|
91
153
|
|
92
|
-
|
154
|
+
private
|
155
|
+
|
156
|
+
#
|
157
|
+
# Determines whether a URI is internal.
|
158
|
+
#
|
159
|
+
# @param [String] uri
|
160
|
+
# The source URI.
|
161
|
+
#
|
162
|
+
# @return [Boolean]
|
163
|
+
#
|
164
|
+
def internal_host?(uri)
|
165
|
+
return unless host = URI.parse(uri).host
|
166
|
+
Resolv.getaddresses(host).all? { |ip| internal_ip?(ip) }
|
167
|
+
rescue URI::Error
|
168
|
+
false
|
93
169
|
end
|
94
170
|
|
171
|
+
# List of internal IP address ranges.
|
172
|
+
#
|
173
|
+
# @see https://tools.ietf.org/html/rfc1918#section-3
|
174
|
+
# @see https://tools.ietf.org/html/rfc4193#section-8
|
175
|
+
INTERNAL_SUBNETS = %w[
|
176
|
+
10.0.0.0/8
|
177
|
+
172.16.0.0/12
|
178
|
+
192.168.0.0/16
|
179
|
+
fc00::/7
|
180
|
+
].map(&IPAddr.method(:new))
|
181
|
+
|
182
|
+
#
|
183
|
+
# Determines whether an IP is internal.
|
184
|
+
#
|
185
|
+
# @param [String] ip
|
186
|
+
# The IPv4/IPv6 address.
|
187
|
+
#
|
188
|
+
# @return [Boolean]
|
189
|
+
#
|
190
|
+
def internal_ip?(ip)
|
191
|
+
INTERNAL_SUBNETS.any? { |subnet| subnet.include?(ip) }
|
192
|
+
end
|
95
193
|
end
|
96
194
|
end
|
97
195
|
end
|
@@ -1,5 +1,5 @@
|
|
1
1
|
#
|
2
|
-
# Copyright (c) 2013-
|
2
|
+
# Copyright (c) 2013-2015 Hal Brodigan (postmodern.mod3 at gmail.com)
|
3
3
|
#
|
4
4
|
# bundler-audit is free software: you can redistribute it and/or modify
|
5
5
|
# it under the terms of the GNU General Public License as published by
|
@@ -18,6 +18,6 @@
|
|
18
18
|
module Bundler
|
19
19
|
module Audit
|
20
20
|
# bundler-audit version
|
21
|
-
VERSION = '0.
|
21
|
+
VERSION = '0.4.0'
|
22
22
|
end
|
23
23
|
end
|
data/spec/advisory_spec.rb
CHANGED
@@ -29,11 +29,30 @@ describe Bundler::Audit::Advisory do
|
|
29
29
|
|
30
30
|
subject { described_class.load(path) }
|
31
31
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
32
|
+
describe '#id' do
|
33
|
+
subject { super().id }
|
34
|
+
it { is_expected.to eq(id) }
|
35
|
+
end
|
36
|
+
|
37
|
+
describe '#url' do
|
38
|
+
subject { super().url }
|
39
|
+
it { is_expected.to eq(data['url']) }
|
40
|
+
end
|
41
|
+
|
42
|
+
describe '#title' do
|
43
|
+
subject { super().title }
|
44
|
+
it { is_expected.to eq(data['title']) }
|
45
|
+
end
|
46
|
+
|
47
|
+
describe '#cvss_v2' do
|
48
|
+
subject { super().cvss_v2 }
|
49
|
+
it { is_expected.to eq(data['cvss_v2']) }
|
50
|
+
end
|
51
|
+
|
52
|
+
describe '#description' do
|
53
|
+
subject { super().description }
|
54
|
+
it { is_expected.to eq(data['description']) }
|
55
|
+
end
|
37
56
|
|
38
57
|
context "YAML data not representing a hash" do
|
39
58
|
it "should raise an exception" do
|
@@ -48,34 +67,41 @@ describe Bundler::Audit::Advisory do
|
|
48
67
|
subject { described_class.load(path).patched_versions }
|
49
68
|
|
50
69
|
it "should all be Gem::Requirement objects" do
|
51
|
-
subject.all? { |version|
|
52
|
-
version.
|
53
|
-
}.
|
70
|
+
expect(subject.all? { |version|
|
71
|
+
expect(version).to be_kind_of(Gem::Requirement)
|
72
|
+
}).to be_truthy
|
54
73
|
end
|
55
74
|
|
56
75
|
it "should parse the versions" do
|
57
|
-
subject.map(&:to_s).
|
76
|
+
expect(subject.map(&:to_s)).to eq(data['patched_versions'])
|
58
77
|
end
|
59
78
|
end
|
60
79
|
end
|
61
80
|
|
62
81
|
describe "#criticality" do
|
63
82
|
context "when cvss_v2 is between 0.0 and 3.3" do
|
64
|
-
before {
|
65
|
-
|
66
|
-
|
83
|
+
before {
|
84
|
+
@advisory = Advisory.new
|
85
|
+
@advisory.cvss_v2 = 3.3
|
86
|
+
}
|
87
|
+
it { expect(@advisory.criticality).to eq(:low) }
|
67
88
|
end
|
68
89
|
|
69
90
|
context "when cvss_v2 is between 3.3 and 6.6" do
|
70
|
-
before {
|
91
|
+
before {
|
92
|
+
@advisory = Advisory.new
|
93
|
+
@advisory.cvss_v2 = 6.6
|
94
|
+
}
|
95
|
+
it { expect(@advisory.criticality).to eq(:medium) }
|
71
96
|
|
72
|
-
its(:criticality) { should == :medium }
|
73
97
|
end
|
74
98
|
|
75
99
|
context "when cvss_v2 is between 6.6 and 10.0" do
|
76
|
-
|
77
|
-
|
78
|
-
|
100
|
+
before {
|
101
|
+
@advisory = Advisory.new
|
102
|
+
@advisory.cvss_v2 = 10.0
|
103
|
+
}
|
104
|
+
it { expect(@advisory.criticality).to eq(:high) }
|
79
105
|
end
|
80
106
|
end
|
81
107
|
|
@@ -86,7 +112,7 @@ describe Bundler::Audit::Advisory do
|
|
86
112
|
let(:version) { Gem::Version.new(an_unaffected_version) }
|
87
113
|
|
88
114
|
it "should return true" do
|
89
|
-
subject.unaffected?(version).
|
115
|
+
expect(subject.unaffected?(version)).to be_truthy
|
90
116
|
end
|
91
117
|
end
|
92
118
|
|
@@ -94,7 +120,7 @@ describe Bundler::Audit::Advisory do
|
|
94
120
|
let(:version) { Gem::Version.new('3.0.9') }
|
95
121
|
|
96
122
|
it "should return false" do
|
97
|
-
subject.unaffected?(version).
|
123
|
+
expect(subject.unaffected?(version)).to be_falsey
|
98
124
|
end
|
99
125
|
end
|
100
126
|
end
|
@@ -106,7 +132,7 @@ describe Bundler::Audit::Advisory do
|
|
106
132
|
let(:version) { Gem::Version.new('3.1.11') }
|
107
133
|
|
108
134
|
it "should return true" do
|
109
|
-
subject.patched?(version).
|
135
|
+
expect(subject.patched?(version)).to be_truthy
|
110
136
|
end
|
111
137
|
end
|
112
138
|
|
@@ -114,7 +140,7 @@ describe Bundler::Audit::Advisory do
|
|
114
140
|
let(:version) { Gem::Version.new('2.9.0') }
|
115
141
|
|
116
142
|
it "should return false" do
|
117
|
-
subject.patched?(version).
|
143
|
+
expect(subject.patched?(version)).to be_falsey
|
118
144
|
end
|
119
145
|
end
|
120
146
|
end
|
@@ -126,7 +152,7 @@ describe Bundler::Audit::Advisory do
|
|
126
152
|
let(:version) { Gem::Version.new('3.1.11') }
|
127
153
|
|
128
154
|
it "should return false" do
|
129
|
-
subject.vulnerable?(version).
|
155
|
+
expect(subject.vulnerable?(version)).to be_falsey
|
130
156
|
end
|
131
157
|
end
|
132
158
|
|
@@ -134,7 +160,7 @@ describe Bundler::Audit::Advisory do
|
|
134
160
|
let(:version) { Gem::Version.new('2.9.0') }
|
135
161
|
|
136
162
|
it "should return true" do
|
137
|
-
subject.vulnerable?(version).
|
163
|
+
expect(subject.vulnerable?(version)).to be_truthy
|
138
164
|
end
|
139
165
|
|
140
166
|
context "when unaffected_versions is not empty" do
|
@@ -144,7 +170,7 @@ describe Bundler::Audit::Advisory do
|
|
144
170
|
let(:version) { Gem::Version.new(an_unaffected_version) }
|
145
171
|
|
146
172
|
it "should return false" do
|
147
|
-
subject.vulnerable?(version).
|
173
|
+
expect(subject.vulnerable?(version)).to be_falsey
|
148
174
|
end
|
149
175
|
end
|
150
176
|
|
@@ -152,7 +178,7 @@ describe Bundler::Audit::Advisory do
|
|
152
178
|
let(:version) { Gem::Version.new('1.2.3') }
|
153
179
|
|
154
180
|
it "should return true" do
|
155
|
-
subject.vulnerable?(version).
|
181
|
+
expect(subject.vulnerable?(version)).to be_truthy
|
156
182
|
end
|
157
183
|
end
|
158
184
|
end
|
data/spec/audit_spec.rb
CHANGED
data/spec/bundle/secure/Gemfile
CHANGED
data/spec/database_spec.rb
CHANGED
@@ -11,7 +11,7 @@ describe Bundler::Audit::Database do
|
|
11
11
|
subject { described_class.path }
|
12
12
|
|
13
13
|
it "it should be a directory" do
|
14
|
-
File.directory?(subject).
|
14
|
+
expect(File.directory?(subject)).to be_truthy
|
15
15
|
end
|
16
16
|
|
17
17
|
it "should prefer the user repo, iff it's as up to date, or more up to date than the vendored one" do
|
@@ -56,7 +56,7 @@ describe Bundler::Audit::Database do
|
|
56
56
|
subject { described_class.new }
|
57
57
|
|
58
58
|
it "should default path to path" do
|
59
|
-
subject.path.
|
59
|
+
expect(subject.path).to eq(described_class.path)
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
@@ -66,15 +66,15 @@ describe Bundler::Audit::Database do
|
|
66
66
|
subject { described_class.new(path) }
|
67
67
|
|
68
68
|
it "should set #path" do
|
69
|
-
subject.path.
|
69
|
+
expect(subject.path).to eq(path)
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
73
|
context "when given an invalid directory" do
|
74
74
|
it "should raise an ArgumentError" do
|
75
|
-
|
75
|
+
expect {
|
76
76
|
described_class.new('/foo/bar/baz')
|
77
|
-
}.
|
77
|
+
}.to raise_error(ArgumentError)
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
@@ -95,16 +95,16 @@ describe Bundler::Audit::Database do
|
|
95
95
|
advisories << advisory
|
96
96
|
end
|
97
97
|
|
98
|
-
advisories.
|
99
|
-
advisories.all? { |advisory|
|
98
|
+
expect(advisories).not_to be_empty
|
99
|
+
expect(advisories.all? { |advisory|
|
100
100
|
advisory.kind_of?(Bundler::Audit::Advisory)
|
101
|
-
}.
|
101
|
+
}).to be_truthy
|
102
102
|
end
|
103
103
|
end
|
104
104
|
|
105
105
|
context "when given no block" do
|
106
106
|
it "should return an Enumerator" do
|
107
|
-
subject.check_gem(gem).
|
107
|
+
expect(subject.check_gem(gem)).to be_kind_of(Enumerable)
|
108
108
|
end
|
109
109
|
end
|
110
110
|
end
|
@@ -126,7 +126,7 @@ describe Bundler::Audit::Database do
|
|
126
126
|
|
127
127
|
describe "#to_s" do
|
128
128
|
it "should return the Database path" do
|
129
|
-
subject.to_s.
|
129
|
+
expect(subject.to_s).to eq(subject.path)
|
130
130
|
end
|
131
131
|
end
|
132
132
|
|
data/spec/integration_spec.rb
CHANGED
@@ -16,20 +16,20 @@ describe "CLI" do
|
|
16
16
|
end
|
17
17
|
|
18
18
|
it "should print a warning" do
|
19
|
-
subject.
|
19
|
+
expect(subject).to include("Vulnerabilities found!")
|
20
20
|
end
|
21
21
|
|
22
22
|
it "should print advisory information for the vulnerable gems" do
|
23
23
|
advisory_pattern = /(Name: [^\n]+
|
24
24
|
Version: \d+.\d+.\d+
|
25
|
-
Advisory:
|
25
|
+
Advisory: CVE-[0-9]{4}-[0-9]{4}
|
26
26
|
Criticality: (High|Medium)
|
27
27
|
URL: http:\/\/(direct|www\.)?osvdb.org\/show\/osvdb\/\d+
|
28
28
|
Title: [^\n]*?
|
29
29
|
Solution: upgrade to ((~>|=>) \d+.\d+.\d+, )*(~>|=>) \d+.\d+.\d+[\s\n]*?)+/
|
30
30
|
|
31
31
|
expect(subject).to match(advisory_pattern)
|
32
|
-
expect(subject).to include("
|
32
|
+
expect(subject).to include("Vulnerabilities found!")
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
@@ -46,7 +46,7 @@ Solution: upgrade to ((~>|=>) \d+.\d+.\d+, )*(~>|=>) \d+.\d+.\d+[\s\n]*?)+/
|
|
46
46
|
end
|
47
47
|
|
48
48
|
it "should not print advisory information for ignored gem" do
|
49
|
-
subject.
|
49
|
+
expect(subject).not_to include("OSVDB-89026")
|
50
50
|
end
|
51
51
|
end
|
52
52
|
|
@@ -59,7 +59,7 @@ Solution: upgrade to ((~>|=>) \d+.\d+.\d+, )*(~>|=>) \d+.\d+.\d+[\s\n]*?)+/
|
|
59
59
|
end
|
60
60
|
|
61
61
|
it "should print warnings about insecure sources" do
|
62
|
-
subject.
|
62
|
+
expect(subject).to include(%{
|
63
63
|
Insecure Source URI found: git://github.com/rails/jquery-rails.git
|
64
64
|
Insecure Source URI found: http://rubygems.org/
|
65
65
|
}.strip)
|
@@ -75,7 +75,7 @@ Insecure Source URI found: http://rubygems.org/
|
|
75
75
|
end
|
76
76
|
|
77
77
|
it "should print nothing when everything is fine" do
|
78
|
-
subject.strip.
|
78
|
+
expect(subject.strip).to eq("No vulnerabilities found")
|
79
79
|
end
|
80
80
|
end
|
81
81
|
end
|
data/spec/scanner_spec.rb
CHANGED
@@ -13,12 +13,12 @@ describe Scanner do
|
|
13
13
|
|
14
14
|
subject.scan { |result| results << result }
|
15
15
|
|
16
|
-
results.
|
16
|
+
expect(results).not_to be_empty
|
17
17
|
end
|
18
18
|
|
19
19
|
context "when not called with a block" do
|
20
20
|
it "should return an Enumerator" do
|
21
|
-
subject.scan.
|
21
|
+
expect(subject.scan).to be_kind_of(Enumerable)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -31,9 +31,9 @@ describe Scanner do
|
|
31
31
|
subject { scanner.scan.to_a }
|
32
32
|
|
33
33
|
it "should match unpatched gems to their advisories" do
|
34
|
-
subject.all? { |result|
|
34
|
+
expect(subject.all? { |result|
|
35
35
|
result.advisory.vulnerable?(result.gem.version)
|
36
|
-
}.
|
36
|
+
}).to be_truthy
|
37
37
|
end
|
38
38
|
|
39
39
|
context "when the :ignore option is given" do
|
@@ -42,7 +42,7 @@ describe Scanner do
|
|
42
42
|
it "should ignore the specified advisories" do
|
43
43
|
ids = subject.map { |result| result.advisory.id }
|
44
44
|
|
45
|
-
ids.
|
45
|
+
expect(ids).not_to include('OSVDB-89026')
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
@@ -55,8 +55,8 @@ describe Scanner do
|
|
55
55
|
subject { scanner.scan.to_a }
|
56
56
|
|
57
57
|
it "should match unpatched gems to their advisories" do
|
58
|
-
subject[0].source.
|
59
|
-
subject[1].source.
|
58
|
+
expect(subject[0].source).to eq('git://github.com/rails/jquery-rails.git')
|
59
|
+
expect(subject[1].source).to eq('http://rubygems.org/')
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
@@ -68,7 +68,7 @@ describe Scanner do
|
|
68
68
|
subject { scanner.scan.to_a }
|
69
69
|
|
70
70
|
it "should print nothing when everything is fine" do
|
71
|
-
subject.
|
71
|
+
expect(subject).to be_empty
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'simplecov'
|
2
|
+
SimpleCov.start
|
3
|
+
|
1
4
|
require 'rspec'
|
2
5
|
require 'bundler/audit/version'
|
3
6
|
|
@@ -19,15 +22,15 @@ module Helpers
|
|
19
22
|
end
|
20
23
|
|
21
24
|
def expect_update_to_clone_repo!
|
22
|
-
Bundler::Audit::Database.
|
23
|
-
|
25
|
+
expect(Bundler::Audit::Database).
|
26
|
+
to receive(:system).
|
24
27
|
with('git', 'clone', Bundler::Audit::Database::VENDORED_PATH, mocked_user_path).
|
25
28
|
and_call_original
|
26
29
|
end
|
27
30
|
|
28
31
|
def expect_update_to_update_repo!
|
29
|
-
Bundler::Audit::Database.
|
30
|
-
|
32
|
+
expect(Bundler::Audit::Database).
|
33
|
+
to receive(:system).
|
31
34
|
with('git', 'pull', 'origin', 'master').
|
32
35
|
and_call_original
|
33
36
|
end
|
metadata
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bundler-audit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
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: 2015-06-30 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
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0.18'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0.18'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '1.2'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.2'
|
41
41
|
description: bundler-audit provides patch-level verification for Bundled apps.
|
@@ -48,12 +48,12 @@ extra_rdoc_files:
|
|
48
48
|
- ChangeLog.md
|
49
49
|
- README.md
|
50
50
|
files:
|
51
|
-
- .document
|
52
|
-
- .gitignore
|
53
|
-
- .gitmodules
|
54
|
-
- .rspec
|
55
|
-
- .travis.yml
|
56
|
-
- .yardopts
|
51
|
+
- ".document"
|
52
|
+
- ".gitignore"
|
53
|
+
- ".gitmodules"
|
54
|
+
- ".rspec"
|
55
|
+
- ".travis.yml"
|
56
|
+
- ".yardopts"
|
57
57
|
- COPYING.txt
|
58
58
|
- ChangeLog.md
|
59
59
|
- Gemfile
|
@@ -62,23 +62,6 @@ files:
|
|
62
62
|
- bin/bundle-audit
|
63
63
|
- bundler-audit.gemspec
|
64
64
|
- data/ruby-advisory-db.ts
|
65
|
-
- gemspec.yml
|
66
|
-
- lib/bundler/audit.rb
|
67
|
-
- lib/bundler/audit/advisory.rb
|
68
|
-
- lib/bundler/audit/cli.rb
|
69
|
-
- lib/bundler/audit/database.rb
|
70
|
-
- lib/bundler/audit/scanner.rb
|
71
|
-
- lib/bundler/audit/version.rb
|
72
|
-
- spec/advisory_spec.rb
|
73
|
-
- spec/audit_spec.rb
|
74
|
-
- spec/bundle/insecure_sources/Gemfile
|
75
|
-
- spec/bundle/secure/Gemfile
|
76
|
-
- spec/bundle/unpatched_gems/Gemfile
|
77
|
-
- spec/database_spec.rb
|
78
|
-
- spec/fixtures/not_a_hash.yml
|
79
|
-
- spec/integration_spec.rb
|
80
|
-
- spec/scanner_spec.rb
|
81
|
-
- spec/spec_helper.rb
|
82
65
|
- data/ruby-advisory-db/.gitignore
|
83
66
|
- data/ruby-advisory-db/.rspec
|
84
67
|
- data/ruby-advisory-db/CONTRIBUTING.md
|
@@ -180,6 +163,23 @@ files:
|
|
180
163
|
- data/ruby-advisory-db/spec/advisory_example.rb
|
181
164
|
- data/ruby-advisory-db/spec/gems_spec.rb
|
182
165
|
- data/ruby-advisory-db/spec/spec_helper.rb
|
166
|
+
- gemspec.yml
|
167
|
+
- lib/bundler/audit.rb
|
168
|
+
- lib/bundler/audit/advisory.rb
|
169
|
+
- lib/bundler/audit/cli.rb
|
170
|
+
- lib/bundler/audit/database.rb
|
171
|
+
- lib/bundler/audit/scanner.rb
|
172
|
+
- lib/bundler/audit/version.rb
|
173
|
+
- spec/advisory_spec.rb
|
174
|
+
- spec/audit_spec.rb
|
175
|
+
- spec/bundle/insecure_sources/Gemfile
|
176
|
+
- spec/bundle/secure/Gemfile
|
177
|
+
- spec/bundle/unpatched_gems/Gemfile
|
178
|
+
- spec/database_spec.rb
|
179
|
+
- spec/fixtures/not_a_hash.yml
|
180
|
+
- spec/integration_spec.rb
|
181
|
+
- spec/scanner_spec.rb
|
182
|
+
- spec/spec_helper.rb
|
183
183
|
homepage: https://github.com/rubysec/bundler-audit#readme
|
184
184
|
licenses:
|
185
185
|
- GPLv3
|
@@ -190,17 +190,17 @@ require_paths:
|
|
190
190
|
- lib
|
191
191
|
required_ruby_version: !ruby/object:Gem::Requirement
|
192
192
|
requirements:
|
193
|
-
- -
|
193
|
+
- - ">="
|
194
194
|
- !ruby/object:Gem::Version
|
195
|
-
version:
|
195
|
+
version: 1.9.3
|
196
196
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
197
197
|
requirements:
|
198
|
-
- -
|
198
|
+
- - ">="
|
199
199
|
- !ruby/object:Gem::Version
|
200
200
|
version: 1.8.0
|
201
201
|
requirements: []
|
202
202
|
rubyforge_project:
|
203
|
-
rubygems_version: 2.
|
203
|
+
rubygems_version: 2.4.7
|
204
204
|
signing_key:
|
205
205
|
specification_version: 4
|
206
206
|
summary: Patch-level verification for Bundler
|