bundler-audit 0.1.0 → 0.2.0
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.
- checksums.yaml +7 -0
- data/.document +1 -1
- data/.gitignore +3 -0
- data/.gitmodules +3 -0
- data/.travis.yml +4 -0
- data/ChangeLog.md +50 -0
- data/Gemfile +12 -0
- data/README.md +51 -69
- data/Rakefile +37 -21
- data/bin/bundle-audit +2 -12
- data/bundler-audit.gemspec +7 -0
- data/data/ruby-advisory-db/.rspec +1 -0
- data/data/ruby-advisory-db/CONTRIBUTING.md +6 -0
- data/data/ruby-advisory-db/CONTRIBUTORS.md +13 -0
- data/data/ruby-advisory-db/Gemfile +3 -0
- data/data/ruby-advisory-db/LICENSE.txt +5 -0
- data/data/ruby-advisory-db/README.md +86 -0
- data/data/ruby-advisory-db/Rakefile +27 -0
- data/data/ruby-advisory-db/gems/actionpack/OSVDB-79727.yml +26 -0
- data/data/ruby-advisory-db/gems/actionpack/OSVDB-84243.yml +28 -0
- data/data/ruby-advisory-db/gems/actionpack/OSVDB-84513.yml +23 -0
- data/data/ruby-advisory-db/gems/actionpack/OSVDB-84515.yml +26 -0
- data/data/{bundler/audit/rails/2013-0156.yml → ruby-advisory-db/gems/actionpack/OSVDB-89026.yml} +8 -3
- data/data/ruby-advisory-db/gems/actionpack/OSVDB-91452.yml +20 -0
- data/data/ruby-advisory-db/gems/actionpack/OSVDB-91454.yml +23 -0
- data/data/ruby-advisory-db/gems/activerecord/OSVDB-82403.yml +25 -0
- data/data/ruby-advisory-db/gems/activerecord/OSVDB-82610.yml +24 -0
- data/data/{bundler/audit/rails/2013-0155.yml → ruby-advisory-db/gems/activerecord/OSVDB-89025.yml} +9 -4
- data/data/{bundler/audit/rails/2013-0276.yml → ruby-advisory-db/gems/activerecord/OSVDB-90072.yml} +8 -3
- data/data/{bundler/audit/rails/2013-0277.yml → ruby-advisory-db/gems/activerecord/OSVDB-90073.yml} +8 -3
- data/data/ruby-advisory-db/gems/activerecord/OSVDB-91453.yml +26 -0
- data/data/ruby-advisory-db/gems/activesupport/OSVDB-79726.yml +26 -0
- data/data/ruby-advisory-db/gems/activesupport/OSVDB-84516.yml +23 -0
- data/data/{bundler/audit/rails/2013-0333.yml → ruby-advisory-db/gems/activesupport/OSVDB-89594.yml} +8 -3
- data/data/ruby-advisory-db/gems/activesupport/OSVDB-91451.yml +28 -0
- data/data/ruby-advisory-db/gems/command_wrap/OSVDB-91450.yml +10 -0
- data/data/ruby-advisory-db/gems/crack/OSVDB-90742.yml +17 -0
- data/data/ruby-advisory-db/gems/cremefraiche/OSVDB-93395.yml +11 -0
- data/data/ruby-advisory-db/gems/curl/OSVDB-91230.yml +12 -0
- data/data/ruby-advisory-db/gems/devise/OSVDB-89642.yml +20 -0
- data/data/ruby-advisory-db/gems/dragonfly/OSVDB-90647.yml +19 -0
- data/data/ruby-advisory-db/gems/enum_column3/OSVDB-94679.yml +9 -0
- data/data/ruby-advisory-db/gems/extlib/OSVDB-90740.yml +18 -0
- data/data/ruby-advisory-db/gems/fastreader/OSVDB-91232.yml +12 -0
- data/data/ruby-advisory-db/gems/fileutils/OSVDB-90715.yml +10 -0
- data/data/ruby-advisory-db/gems/fileutils/OSVDB-90716.yml +10 -0
- data/data/ruby-advisory-db/gems/fileutils/OSVDB-90717.yml +10 -0
- data/data/ruby-advisory-db/gems/flash_tool/OSVDB-90829.yml +9 -0
- data/data/ruby-advisory-db/gems/ftpd/OSVDB-90784.yml +18 -0
- data/data/ruby-advisory-db/gems/gtk2/OSVDB-40774.yml +20 -0
- data/data/ruby-advisory-db/gems/httparty/OSVDB-90741.yml +19 -0
- data/data/{bundler/audit/json/2013-0269.yml → ruby-advisory-db/gems/json/OSVDB-90074.yml} +8 -4
- data/data/ruby-advisory-db/gems/karteek-docsplit/OSVDB-92117.yml +10 -0
- data/data/ruby-advisory-db/gems/kelredd-pruview/OSVDB-92228.yml +10 -0
- data/data/ruby-advisory-db/gems/ldoce/OSVDB-91870.yml +10 -0
- data/data/ruby-advisory-db/gems/loofah/OSVDB-90945.yml +21 -0
- data/data/ruby-advisory-db/gems/mail/OSVDB-70667.yml +21 -0
- data/data/ruby-advisory-db/gems/mail/OSVDB-81631.yml +14 -0
- data/data/ruby-advisory-db/gems/mail/OSVDB-81632.yml +16 -0
- data/data/ruby-advisory-db/gems/md2pdf/OSVDB-92290.yml +10 -0
- data/data/ruby-advisory-db/gems/mini_magick/OSVDB-91231.yml +15 -0
- data/data/ruby-advisory-db/gems/multi_xml/OSVDB-89148.yml +16 -0
- data/data/ruby-advisory-db/gems/newrelic_rpm/OSVDB-90189.yml +17 -0
- data/data/ruby-advisory-db/gems/nori/OSVDB-90196.yml +19 -0
- data/data/ruby-advisory-db/gems/omniauth-oauth2/OSVDB-90264.yml +16 -0
- data/data/ruby-advisory-db/gems/pdfkit/OSVDB-90867.yml +11 -0
- data/data/{bundler/audit/rack/2013-0263.yml → ruby-advisory-db/gems/rack/OSVDB-89939.yml} +11 -8
- data/data/ruby-advisory-db/gems/rack-cache/OSVDB-83077.yml +18 -0
- data/data/ruby-advisory-db/gems/rdoc/OSVDB-90004.yml +27 -0
- data/data/ruby-advisory-db/gems/rgpg/OSVDB-95948.yml +13 -0
- data/data/ruby-advisory-db/gems/ruby_parser/OSVDB-90561.yml +11 -0
- data/data/ruby-advisory-db/gems/spree/OSVDB-91216.yml +10 -0
- data/data/ruby-advisory-db/gems/spree/OSVDB-91217.yml +10 -0
- data/data/ruby-advisory-db/gems/spree/OSVDB-91218.yml +10 -0
- data/data/ruby-advisory-db/gems/spree/OSVDB-91219.yml +10 -0
- data/data/ruby-advisory-db/gems/thumbshooter/OSVDB-91839.yml +10 -0
- data/data/ruby-advisory-db/lib/scrape.rb +87 -0
- data/data/ruby-advisory-db/spec/advisory_example.rb +165 -0
- data/data/ruby-advisory-db/spec/gems_spec.rb +8 -0
- data/data/ruby-advisory-db/spec/spec_helper.rb +1 -0
- data/gemspec.yml +4 -7
- data/lib/bundler/audit/advisory.rb +51 -9
- data/lib/bundler/audit/cli.rb +33 -12
- data/lib/bundler/audit/database.rb +1 -30
- data/lib/bundler/audit/scanner.rb +97 -0
- data/lib/bundler/audit/version.rb +1 -1
- data/spec/advisory_spec.rb +67 -7
- data/spec/bundle/insecure_sources/Gemfile +39 -0
- data/spec/bundle/secure/Gemfile +38 -0
- data/spec/database_spec.rb +1 -32
- data/spec/integration_spec.rb +132 -0
- data/spec/scanner_spec.rb +74 -0
- data/spec/spec_helper.rb +14 -1
- metadata +89 -74
- data/LICENSE.txt +0 -20
- data/spec/bundle/Gemfile.lock +0 -92
- /data/spec/bundle/{Gemfile → unpatched_gems/Gemfile} +0 -0
|
@@ -19,11 +19,13 @@ require 'yaml'
|
|
|
19
19
|
|
|
20
20
|
module Bundler
|
|
21
21
|
module Audit
|
|
22
|
-
class Advisory < Struct.new(:
|
|
22
|
+
class Advisory < Struct.new(:path,
|
|
23
|
+
:id,
|
|
23
24
|
:url,
|
|
24
25
|
:title,
|
|
25
26
|
:description,
|
|
26
27
|
:cvss_v2,
|
|
28
|
+
:unaffected_versions,
|
|
27
29
|
:patched_versions)
|
|
28
30
|
|
|
29
31
|
#
|
|
@@ -37,22 +39,28 @@ module Bundler
|
|
|
37
39
|
# @api semipublic
|
|
38
40
|
#
|
|
39
41
|
def self.load(path)
|
|
40
|
-
|
|
42
|
+
id = File.basename(path).chomp('.yml')
|
|
41
43
|
data = YAML.load_file(path)
|
|
42
44
|
|
|
43
45
|
unless data.kind_of?(Hash)
|
|
44
46
|
raise("advisory data in #{path.dump} was not a Hash")
|
|
45
47
|
end
|
|
46
48
|
|
|
49
|
+
parse_versions = lambda { |versions|
|
|
50
|
+
Array(versions).map do |version|
|
|
51
|
+
Gem::Requirement.new(*version.split(', '))
|
|
52
|
+
end
|
|
53
|
+
}
|
|
54
|
+
|
|
47
55
|
return new(
|
|
48
|
-
|
|
56
|
+
path,
|
|
57
|
+
id,
|
|
49
58
|
data['url'],
|
|
50
59
|
data['title'],
|
|
51
60
|
data['description'],
|
|
52
61
|
data['cvss_v2'],
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
},
|
|
62
|
+
parse_versions[data['unaffected_versions']],
|
|
63
|
+
parse_versions[data['patched_versions']]
|
|
56
64
|
)
|
|
57
65
|
end
|
|
58
66
|
|
|
@@ -70,6 +78,40 @@ module Bundler
|
|
|
70
78
|
end
|
|
71
79
|
end
|
|
72
80
|
|
|
81
|
+
#
|
|
82
|
+
# Checks whether the version is not affected by the advisory.
|
|
83
|
+
#
|
|
84
|
+
# @param [Gem::Version] version
|
|
85
|
+
# The version to compare against {#unaffected_version}.
|
|
86
|
+
#
|
|
87
|
+
# @return [Boolean]
|
|
88
|
+
# Specifies whether the version is not affected by the advisory.
|
|
89
|
+
#
|
|
90
|
+
# @since 0.2.0
|
|
91
|
+
#
|
|
92
|
+
def unaffected?(version)
|
|
93
|
+
unaffected_versions.any? do |unaffected_version|
|
|
94
|
+
unaffected_version === version
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
#
|
|
99
|
+
# Checks whether the version is patched against the advisory.
|
|
100
|
+
#
|
|
101
|
+
# @param [Gem::Version] version
|
|
102
|
+
# The version to compare against {#patched_version}.
|
|
103
|
+
#
|
|
104
|
+
# @return [Boolean]
|
|
105
|
+
# Specifies whether the version is patched against the advisory.
|
|
106
|
+
#
|
|
107
|
+
# @since 0.2.0
|
|
108
|
+
#
|
|
109
|
+
def patched?(version)
|
|
110
|
+
patched_versions.any? do |patched_version|
|
|
111
|
+
patched_version === version
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
73
115
|
#
|
|
74
116
|
# Checks whether the version is vulnerable to the advisory.
|
|
75
117
|
#
|
|
@@ -80,11 +122,11 @@ module Bundler
|
|
|
80
122
|
# Specifies whether the version is vulnerable to the advisory or not.
|
|
81
123
|
#
|
|
82
124
|
def vulnerable?(version)
|
|
83
|
-
!
|
|
84
|
-
patched_version === version
|
|
85
|
-
end
|
|
125
|
+
!patched?(version) && !unaffected?(version)
|
|
86
126
|
end
|
|
87
127
|
|
|
128
|
+
alias to_s id
|
|
129
|
+
|
|
88
130
|
end
|
|
89
131
|
end
|
|
90
132
|
end
|
data/lib/bundler/audit/cli.rb
CHANGED
|
@@ -15,11 +15,11 @@
|
|
|
15
15
|
# along with bundler-audit. If not, see <http://www.gnu.org/licenses/>.
|
|
16
16
|
#
|
|
17
17
|
|
|
18
|
-
require 'bundler/audit/
|
|
18
|
+
require 'bundler/audit/scanner'
|
|
19
19
|
require 'bundler/audit/version'
|
|
20
20
|
|
|
21
|
-
require 'bundler/vendored_thor'
|
|
22
21
|
require 'bundler'
|
|
22
|
+
require 'bundler/vendored_thor'
|
|
23
23
|
|
|
24
24
|
module Bundler
|
|
25
25
|
module Audit
|
|
@@ -30,21 +30,26 @@ module Bundler
|
|
|
30
30
|
|
|
31
31
|
desc 'check', 'Checks the Gemfile.lock for insecure dependencies'
|
|
32
32
|
method_option :verbose, :type => :boolean, :aliases => '-v'
|
|
33
|
+
method_option :ignore, :type => :array, :aliases => '-i'
|
|
33
34
|
|
|
34
35
|
def check
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
vulnerable = false
|
|
36
|
+
scanner = Scanner.new
|
|
37
|
+
vulnerable = false
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
scanner.scan(:ignore => options.ignore) do |result|
|
|
40
40
|
vulnerable = true
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
case result
|
|
43
|
+
when Scanner::InsecureSource
|
|
44
|
+
print_warning "Insecure Source URI found: #{result.source}"
|
|
45
|
+
when Scanner::UnpatchedGem
|
|
46
|
+
print_advisory result.gem, result.advisory
|
|
47
|
+
end
|
|
43
48
|
end
|
|
44
49
|
|
|
45
50
|
if vulnerable
|
|
46
51
|
say "Unpatched versions found!", :red
|
|
47
|
-
|
|
52
|
+
exit 1
|
|
48
53
|
else
|
|
49
54
|
say "No unpatched versions found", :green
|
|
50
55
|
end
|
|
@@ -59,6 +64,15 @@ module Bundler
|
|
|
59
64
|
|
|
60
65
|
protected
|
|
61
66
|
|
|
67
|
+
def say(string="", color=nil)
|
|
68
|
+
color = nil unless $stdout.tty?
|
|
69
|
+
super(string, color)
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def print_warning(message)
|
|
73
|
+
say message, :yellow
|
|
74
|
+
end
|
|
75
|
+
|
|
62
76
|
def print_advisory(gem, advisory)
|
|
63
77
|
say "Name: ", :red
|
|
64
78
|
say gem.name
|
|
@@ -66,14 +80,15 @@ module Bundler
|
|
|
66
80
|
say "Version: ", :red
|
|
67
81
|
say gem.version
|
|
68
82
|
|
|
69
|
-
say "
|
|
70
|
-
say advisory.
|
|
83
|
+
say "Advisory: ", :red
|
|
84
|
+
say advisory.id
|
|
71
85
|
|
|
72
86
|
say "Criticality: ", :red
|
|
73
87
|
case advisory.criticality
|
|
74
88
|
when :low then say "Low"
|
|
75
89
|
when :medium then say "Medium", :yellow
|
|
76
90
|
when :high then say "High", [:red, :bold]
|
|
91
|
+
else say "Unknown"
|
|
77
92
|
end
|
|
78
93
|
|
|
79
94
|
say "URL: ", :red
|
|
@@ -91,8 +106,14 @@ module Bundler
|
|
|
91
106
|
say advisory.title
|
|
92
107
|
end
|
|
93
108
|
|
|
94
|
-
|
|
95
|
-
|
|
109
|
+
unless advisory.patched_versions.empty?
|
|
110
|
+
say "Solution: upgrade to ", :red
|
|
111
|
+
say advisory.patched_versions.join(', ')
|
|
112
|
+
else
|
|
113
|
+
say "Solution: ", :red
|
|
114
|
+
say "remove or disable this gem until a patch is available!", [:red, :bold]
|
|
115
|
+
end
|
|
116
|
+
|
|
96
117
|
say
|
|
97
118
|
end
|
|
98
119
|
|
|
@@ -28,7 +28,7 @@ module Bundler
|
|
|
28
28
|
class Database
|
|
29
29
|
|
|
30
30
|
# directory containing advisories
|
|
31
|
-
PATH = File.expand_path(File.join(File.dirname(__FILE__),'..','..','..','data','
|
|
31
|
+
PATH = File.expand_path(File.join(File.dirname(__FILE__),'..','..','..','data','ruby-advisory-db','gems'))
|
|
32
32
|
|
|
33
33
|
# The path to the advisory database
|
|
34
34
|
attr_reader :path
|
|
@@ -119,35 +119,6 @@ module Bundler
|
|
|
119
119
|
end
|
|
120
120
|
end
|
|
121
121
|
|
|
122
|
-
#
|
|
123
|
-
# Verifies whether the bundled gems are effected by any advisories.
|
|
124
|
-
#
|
|
125
|
-
# @param [Bundle::Environment] environment
|
|
126
|
-
# The bundled gems.
|
|
127
|
-
#
|
|
128
|
-
# @yield [gem, advisory]
|
|
129
|
-
# If a block is given, each advisory that effects a gem within the
|
|
130
|
-
# bundle will be passed.
|
|
131
|
-
#
|
|
132
|
-
# @yieldparam [Gem::Specification] gem
|
|
133
|
-
# The gem effected by the advisory.
|
|
134
|
-
#
|
|
135
|
-
# @yieldparam [Advisory] advisory
|
|
136
|
-
# An advisory that effects a gem within the bundle.
|
|
137
|
-
#
|
|
138
|
-
# @return [Enumerator]
|
|
139
|
-
# If no block is given, an Enumerator will be returned.
|
|
140
|
-
#
|
|
141
|
-
def check_bundle(environment)
|
|
142
|
-
return enum_for(__method__,environment) unless block_given?
|
|
143
|
-
|
|
144
|
-
environment.gems.each do |gem|
|
|
145
|
-
check_gem(gem) do |advisory|
|
|
146
|
-
yield gem, advisory
|
|
147
|
-
end
|
|
148
|
-
end
|
|
149
|
-
end
|
|
150
|
-
|
|
151
122
|
#
|
|
152
123
|
# The number of advisories within the database.
|
|
153
124
|
#
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
require 'bundler'
|
|
2
|
+
require 'bundler/audit/database'
|
|
3
|
+
require 'bundler/lockfile_parser'
|
|
4
|
+
|
|
5
|
+
require 'set'
|
|
6
|
+
|
|
7
|
+
module Bundler
|
|
8
|
+
module Audit
|
|
9
|
+
class Scanner
|
|
10
|
+
|
|
11
|
+
# Represents a plain-text source
|
|
12
|
+
InsecureSource = Struct.new(:source)
|
|
13
|
+
|
|
14
|
+
# Represents a gem that is covered by an Advisory
|
|
15
|
+
UnpatchedGem = Struct.new(:gem, :advisory)
|
|
16
|
+
|
|
17
|
+
# The advisory database
|
|
18
|
+
#
|
|
19
|
+
# @return [Database]
|
|
20
|
+
attr_reader :database
|
|
21
|
+
|
|
22
|
+
# Project root directory
|
|
23
|
+
attr_reader :root
|
|
24
|
+
|
|
25
|
+
# The parsed `Gemfile.lock` from the project
|
|
26
|
+
#
|
|
27
|
+
# @return [Bundler::LockfileParser]
|
|
28
|
+
attr_reader :lockfile
|
|
29
|
+
|
|
30
|
+
#
|
|
31
|
+
# Initializes a scanner.
|
|
32
|
+
#
|
|
33
|
+
# @param [String] root
|
|
34
|
+
# The path to the project root.
|
|
35
|
+
#
|
|
36
|
+
def initialize(root=Dir.pwd)
|
|
37
|
+
@root = File.expand_path(root)
|
|
38
|
+
@database = Database.new
|
|
39
|
+
@lockfile = LockfileParser.new(
|
|
40
|
+
File.read(File.join(@root,'Gemfile.lock'))
|
|
41
|
+
)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
#
|
|
45
|
+
# Scans the project for issues.
|
|
46
|
+
#
|
|
47
|
+
# @param [Hash] options
|
|
48
|
+
# Additional options.
|
|
49
|
+
#
|
|
50
|
+
# @option options [Array<String>] :ignore
|
|
51
|
+
# The advisories to ignore.
|
|
52
|
+
#
|
|
53
|
+
# @yield [result]
|
|
54
|
+
# The given block will be passed the results of the scan.
|
|
55
|
+
#
|
|
56
|
+
# @yieldparam [InsecureSource, UnpatchedGem] result
|
|
57
|
+
# A result from the scan.
|
|
58
|
+
#
|
|
59
|
+
# @return [Enumerator]
|
|
60
|
+
# If no block is given, an Enumerator will be returned.
|
|
61
|
+
#
|
|
62
|
+
def scan(options={})
|
|
63
|
+
return enum_for(__method__,options) unless block_given?
|
|
64
|
+
|
|
65
|
+
ignore = Set[]
|
|
66
|
+
ignore += options[:ignore] if options[:ignore]
|
|
67
|
+
|
|
68
|
+
@lockfile.sources.map do |source|
|
|
69
|
+
case source
|
|
70
|
+
when Source::Git
|
|
71
|
+
case source.uri
|
|
72
|
+
when /^git:/, /^http:/
|
|
73
|
+
yield InsecureSource.new(source.uri)
|
|
74
|
+
end
|
|
75
|
+
when Source::Rubygems
|
|
76
|
+
source.remotes.each do |uri|
|
|
77
|
+
if uri.scheme == 'http'
|
|
78
|
+
yield InsecureSource.new(uri.to_s)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
@lockfile.specs.each do |gem|
|
|
85
|
+
@database.check_gem(gem) do |advisory|
|
|
86
|
+
unless ignore.include?(advisory.id)
|
|
87
|
+
yield UnpatchedGem.new(gem,advisory)
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
return self
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
data/spec/advisory_spec.rb
CHANGED
|
@@ -4,16 +4,16 @@ require 'bundler/audit/advisory'
|
|
|
4
4
|
|
|
5
5
|
describe Bundler::Audit::Advisory do
|
|
6
6
|
let(:root) { Bundler::Audit::Database::PATH }
|
|
7
|
-
let(:gem) { '
|
|
8
|
-
let(:
|
|
9
|
-
let(:path) { File.join(root,gem,"#{
|
|
7
|
+
let(:gem) { 'actionpack' }
|
|
8
|
+
let(:id) { 'OSVDB-84243' }
|
|
9
|
+
let(:path) { File.join(root,gem,"#{id}.yml") }
|
|
10
10
|
|
|
11
11
|
describe "load" do
|
|
12
12
|
let(:data) { YAML.load_file(path) }
|
|
13
13
|
|
|
14
14
|
subject { described_class.load(path) }
|
|
15
15
|
|
|
16
|
-
its(:
|
|
16
|
+
its(:id) { should == id }
|
|
17
17
|
its(:url) { should == data['url'] }
|
|
18
18
|
its(:title) { should == data['title'] }
|
|
19
19
|
its(:cvss_v2) { should == data['cvss_v2'] }
|
|
@@ -54,10 +54,50 @@ describe Bundler::Audit::Advisory do
|
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
+
describe "#unaffected?" do
|
|
58
|
+
subject { described_class.load(path) }
|
|
59
|
+
|
|
60
|
+
context "when passed a version that matches one unaffected version" do
|
|
61
|
+
let(:version) { Gem::Version.new('2.3.10') }
|
|
62
|
+
|
|
63
|
+
it "should return true" do
|
|
64
|
+
subject.unaffected?(version).should be_true
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
context "when passed a version that matches no unaffected version" do
|
|
69
|
+
let(:version) { Gem::Version.new('3.0.9') }
|
|
70
|
+
|
|
71
|
+
it "should return false" do
|
|
72
|
+
subject.unaffected?(version).should be_false
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
describe "#patched?" do
|
|
78
|
+
subject { described_class.load(path) }
|
|
79
|
+
|
|
80
|
+
context "when passed a version that matches one patched version" do
|
|
81
|
+
let(:version) { Gem::Version.new('3.1.11') }
|
|
82
|
+
|
|
83
|
+
it "should return true" do
|
|
84
|
+
subject.patched?(version).should be_true
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
context "when passed a version that matches no patched version" do
|
|
89
|
+
let(:version) { Gem::Version.new('2.9.0') }
|
|
90
|
+
|
|
91
|
+
it "should return false" do
|
|
92
|
+
subject.patched?(version).should be_false
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
57
97
|
describe "#vulnerable?" do
|
|
58
98
|
subject { described_class.load(path) }
|
|
59
99
|
|
|
60
|
-
context "when passed a version that matches one
|
|
100
|
+
context "when passed a version that matches one patched version" do
|
|
61
101
|
let(:version) { Gem::Version.new('3.1.11') }
|
|
62
102
|
|
|
63
103
|
it "should return false" do
|
|
@@ -65,12 +105,32 @@ describe Bundler::Audit::Advisory do
|
|
|
65
105
|
end
|
|
66
106
|
end
|
|
67
107
|
|
|
68
|
-
context "when passed a version that matches no
|
|
69
|
-
let(:version) { Gem::Version.new('
|
|
108
|
+
context "when passed a version that matches no patched version" do
|
|
109
|
+
let(:version) { Gem::Version.new('2.9.0') }
|
|
70
110
|
|
|
71
111
|
it "should return true" do
|
|
72
112
|
subject.vulnerable?(version).should be_true
|
|
73
113
|
end
|
|
114
|
+
|
|
115
|
+
context "when unaffected_versions is not empty" do
|
|
116
|
+
subject { described_class.load(path) }
|
|
117
|
+
|
|
118
|
+
context "when passed a version that matches one unaffected version" do
|
|
119
|
+
let(:version) { Gem::Version.new('2.3.12') }
|
|
120
|
+
|
|
121
|
+
it "should return false" do
|
|
122
|
+
subject.vulnerable?(version).should be_false
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
context "when passed a version that matches no unaffected version" do
|
|
127
|
+
let(:version) { Gem::Version.new('1.2.3') }
|
|
128
|
+
|
|
129
|
+
it "should return true" do
|
|
130
|
+
subject.vulnerable?(version).should be_true
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
74
134
|
end
|
|
75
135
|
end
|
|
76
136
|
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
source 'http://rubygems.org'
|
|
2
|
+
|
|
3
|
+
gem 'rails', '3.2.12'
|
|
4
|
+
|
|
5
|
+
# Bundle edge Rails instead:
|
|
6
|
+
# gem 'rails', :git => 'git://github.com/rails/rails.git'
|
|
7
|
+
|
|
8
|
+
gem 'sqlite3'
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# Gems used only for assets and not required
|
|
12
|
+
# in production environments by default.
|
|
13
|
+
group :assets do
|
|
14
|
+
# gem 'sass-rails', '~> 3.2.3'
|
|
15
|
+
# gem 'coffee-rails', '~> 3.2.1'
|
|
16
|
+
|
|
17
|
+
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
|
|
18
|
+
# gem 'therubyracer', :platforms => :ruby
|
|
19
|
+
|
|
20
|
+
# gem 'uglifier', '>= 1.0.3'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
gem 'jquery-rails', :git => 'git://github.com/rails/jquery-rails.git',
|
|
24
|
+
:tag => 'v2.2.1'
|
|
25
|
+
|
|
26
|
+
# To use ActiveModel has_secure_password
|
|
27
|
+
# gem 'bcrypt-ruby', '~> 3.0.0'
|
|
28
|
+
|
|
29
|
+
# To use Jbuilder templates for JSON
|
|
30
|
+
# gem 'jbuilder'
|
|
31
|
+
|
|
32
|
+
# Use unicorn as the app server
|
|
33
|
+
# gem 'unicorn'
|
|
34
|
+
|
|
35
|
+
# Deploy with Capistrano
|
|
36
|
+
# gem 'capistrano'
|
|
37
|
+
|
|
38
|
+
# To use debugger
|
|
39
|
+
# gem 'debugger'
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
source 'https://rubygems.org'
|
|
2
|
+
|
|
3
|
+
gem 'rails', '3.2.14'
|
|
4
|
+
|
|
5
|
+
# Bundle edge Rails instead:
|
|
6
|
+
# gem 'rails', :git => 'git://github.com/rails/rails.git'
|
|
7
|
+
|
|
8
|
+
gem 'sqlite3'
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
# Gems used only for assets and not required
|
|
12
|
+
# in production environments by default.
|
|
13
|
+
group :assets do
|
|
14
|
+
# gem 'sass-rails', '~> 3.2.3'
|
|
15
|
+
# gem 'coffee-rails', '~> 3.2.1'
|
|
16
|
+
|
|
17
|
+
# See https://github.com/sstephenson/execjs#readme for more supported runtimes
|
|
18
|
+
# gem 'therubyracer', :platforms => :ruby
|
|
19
|
+
|
|
20
|
+
# gem 'uglifier', '>= 1.0.3'
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
gem 'jquery-rails'
|
|
24
|
+
|
|
25
|
+
# To use ActiveModel has_secure_password
|
|
26
|
+
# gem 'bcrypt-ruby', '~> 3.0.0'
|
|
27
|
+
|
|
28
|
+
# To use Jbuilder templates for JSON
|
|
29
|
+
# gem 'jbuilder'
|
|
30
|
+
|
|
31
|
+
# Use unicorn as the app server
|
|
32
|
+
# gem 'unicorn'
|
|
33
|
+
|
|
34
|
+
# Deploy with Capistrano
|
|
35
|
+
# gem 'capistrano'
|
|
36
|
+
|
|
37
|
+
# To use debugger
|
|
38
|
+
# gem 'debugger'
|
data/spec/database_spec.rb
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
require 'bundler/audit/database'
|
|
3
|
-
|
|
4
|
-
require 'bundler'
|
|
5
3
|
require 'tmpdir'
|
|
6
4
|
|
|
7
5
|
describe Bundler::Audit::Database do
|
|
@@ -44,7 +42,7 @@ describe Bundler::Audit::Database do
|
|
|
44
42
|
describe "#check_gem" do
|
|
45
43
|
let(:gem) do
|
|
46
44
|
Gem::Specification.new do |s|
|
|
47
|
-
s.name = '
|
|
45
|
+
s.name = 'actionpack'
|
|
48
46
|
s.version = '3.1.9'
|
|
49
47
|
end
|
|
50
48
|
end
|
|
@@ -71,35 +69,6 @@ describe Bundler::Audit::Database do
|
|
|
71
69
|
end
|
|
72
70
|
end
|
|
73
71
|
|
|
74
|
-
describe "#check_bundle" do
|
|
75
|
-
let(:path) { File.join(File.dirname(__FILE__),'bundle') }
|
|
76
|
-
let(:bundle) do
|
|
77
|
-
Dir.chdir(path) { Bundler.load }
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
context "when given a block" do
|
|
81
|
-
it "should yield every advisory effecting the bundle" do
|
|
82
|
-
advisories = []
|
|
83
|
-
|
|
84
|
-
subject.check_bundle(bundle) do |gem,advisory|
|
|
85
|
-
advisories << [gem, advisory]
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
advisories.should_not be_empty
|
|
89
|
-
advisories.all? { |gem,advisory|
|
|
90
|
-
gem.kind_of?(Gem::Specification) &&
|
|
91
|
-
advisory.kind_of?(Bundler::Audit::Advisory)
|
|
92
|
-
}.should be_true
|
|
93
|
-
end
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
context "when given no block" do
|
|
97
|
-
it "should return an Enumerator" do
|
|
98
|
-
subject.check_bundle(bundle).should be_kind_of(Enumerable)
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
|
-
|
|
103
72
|
describe "#size" do
|
|
104
73
|
it { subject.size.should > 0 }
|
|
105
74
|
end
|