Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to ignore specific Gemfile groups #228

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,10 @@ Ignore specific advisories:

$ bundle audit check --ignore OSVDB-108664

Ignore gems from specific Gemfile groups:

$ bundle audit check --ignore-groups development test

Rake task:

```ruby
Expand Down
2 changes: 1 addition & 1 deletion data/ruby-advisory-db
Submodule ruby-advisory-db updated 168 files
2 changes: 1 addition & 1 deletion data/ruby-advisory-db.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2017-06-13 16:51:56 UTC
2019-08-19 13:52:52 UTC
3 changes: 2 additions & 1 deletion lib/bundler/audit/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class CLI < ::Thor
method_option :quiet, :type => :boolean, :aliases => '-q'
method_option :verbose, :type => :boolean, :aliases => '-v'
method_option :ignore, :type => :array, :aliases => '-i'
method_option :ignore_groups, :type => :array
method_option :update, :type => :boolean, :aliases => '-u'

def check
Expand All @@ -41,7 +42,7 @@ def check
scanner = Scanner.new
vulnerable = false

scanner.scan(:ignore => options.ignore) do |result|
scanner.scan(:ignore => options.ignore, :ignore_groups => options.ignore_groups) do |result|
vulnerable = true

case result
Expand Down
42 changes: 42 additions & 0 deletions lib/bundler/audit/gemfile.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
require 'set'

module Bundler
module Audit
class Gemfile
def initialize(env)
@env = env
end

def groups
groups = Set.new
@env.current_dependencies.each do |dependency|
groups += dependency.groups
end
groups.to_a
end

def dependencies_for(groups)
groups.map!(&:to_sym)
dependencies = Set.new
parent_dependencies = @env.current_dependencies.select { |dep| (dep.groups & groups).any? }

while parent_dependencies.any?
tmp = Set.new
parent_dependencies.each do |dependency|
dependencies << dependency
child_dependencies = spec_for_dependency(dependency).runtime_dependencies.to_set
tmp += child_dependencies
end
parent_dependencies = tmp
end
dependencies.to_a
end

private

def spec_for_dependency(dependency)
@env.requested_specs.find { |spec| spec.name == dependency.name }
end
end
end
end
23 changes: 20 additions & 3 deletions lib/bundler/audit/scanner.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require 'bundler'
require 'bundler/audit/database'
require 'bundler/audit/gemfile'
require 'bundler/lockfile_parser'

require 'ipaddr'
Expand Down Expand Up @@ -68,9 +69,6 @@ def initialize(root=Dir.pwd,gemfile_lock='Gemfile.lock')
def scan(options={},&block)
return enum_for(__method__,options) unless block

ignore = Set[]
ignore += options[:ignore] if options[:ignore]

scan_sources(options,&block)
scan_specs(options,&block)

Expand Down Expand Up @@ -127,6 +125,9 @@ def scan_sources(options={})
# @option options [Array<String>] :ignore
# The advisories to ignore.
#
# @option options [Array<String>] :ignore_groups
# The groups from Gemfile to ignore.
#
# @yield [result]
# The given block will be passed the results of the scan.
#
Expand All @@ -146,7 +147,12 @@ def scan_specs(options={})
ignore = Set[]
ignore += options[:ignore] if options[:ignore]

gem_names = gems_to_check(options)

@lockfile.specs.each do |gem|
is_ignored = gem_names != :all && !gem_names.include?(gem.name)
next if is_ignored

@database.check_gem(gem) do |advisory|
is_ignored = ignore.intersect?(advisory.identifiers.to_set)
next if is_ignored
Expand Down Expand Up @@ -208,6 +214,17 @@ def internal_host?(host)
def internal_ip?(ip)
INTERNAL_SUBNETS.any? { |subnet| subnet.include?(ip) }
end

def gems_to_check(options)
if options[:ignore_groups]
ENV["BUNDLE_GEMFILE"] = File.join(@root, "Gemfile")
gemfile = Gemfile.new(Bundler.load)
groups_to_check = gemfile.groups - options[:ignore_groups].map!(&:to_sym)
gemfile.dependencies_for(groups_to_check).map(&:name).to_set
else
:all
end
end
end
end
end
2 changes: 1 addition & 1 deletion spec/bundle/insecure_sources/Gemfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
source 'http://rubygems.org'

gem 'rails'
gem 'rails', '~> 5.2' # rails >= 6 requires ruby >= 2.5.0
gem 'jquery-rails', git: 'git://github.com/rails/jquery-rails.git'
4 changes: 4 additions & 0 deletions spec/bundle/unpatched_gems/Gemfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
source 'https://rubygems.org'

gem 'activerecord', '3.2.10'

group :test do
gem 'redis-store', '1.3.0'
end
10 changes: 10 additions & 0 deletions spec/scanner_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
it "should match unpatched gems to their advisories" do
ids = subject.map { |result| result.advisory.id }
expect(ids).to include('OSVDB-89025')
expect(ids).to include('CVE-2017-1000248')
expect(subject.all? { |result|
result.advisory.vulnerable?(result.gem.version)
}).to be_truthy
Expand All @@ -46,6 +47,15 @@
expect(ids).not_to include('OSVDB-89025')
end
end

context "when the :ignore_groups option is given" do
subject { scanner.scan(:ignore_groups => ['test']) }

it "should ignore gems from the specified groups" do
ids = subject.map { |result| result.advisory.id }
expect(ids).not_to include('OSVDB-89025')
end
end
end

context "when auditing a bundle with insecure sources" do
Expand Down