Skip to content

Commit

Permalink
Add criticality filtering to cli
Browse files Browse the repository at this point in the history
Why?

When utilizing bundler-audit on CI, it can be helpful
to filter criticality to find higher criticality gems.

What?

* Adds filter (--filter or -f) command line argument that
accepts array of values
* Filters within Audit::Scanner to remove filtered out advisories
  • Loading branch information
joshmfrankel committed Jun 21, 2020
1 parent 4d10767 commit ebc6516
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 5 deletions.
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

Filter results by criticality level (low, medium, high):

$ bundle-audit check --filter medium high

Rake task:

```ruby
Expand Down
3 changes: 2 additions & 1 deletion lib/bundler/audit/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,15 @@ class CLI < ::Thor
method_option :verbose, :type => :boolean, :aliases => '-v'
method_option :ignore, :type => :array, :aliases => '-i'
method_option :update, :type => :boolean, :aliases => '-u'
method_option :filter, :type => :array, :aliases => '-f'

def check
update if options[:update]

scanner = Scanner.new
vulnerable = false

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

case result
Expand Down
16 changes: 12 additions & 4 deletions lib/bundler/audit/scanner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ def initialize(root=Dir.pwd,gemfile_lock='Gemfile.lock')
# @option options [Array<String>] :ignore
# The advisories to ignore.
#
# @option options [Array<String>] :filter
# The criticalities to filter.
#
# @yield [result]
# The given block will be passed the results of the scan.
#
Expand All @@ -68,13 +71,10 @@ 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)

return self
self
end

#
Expand Down Expand Up @@ -127,6 +127,9 @@ def scan_sources(options={})
# @option options [Array<String>] :ignore
# The advisories to ignore.
#
# @option options [Array<String>] :filter
# The criticalities to filter.
#
# @yield [result]
# The given block will be passed the results of the scan.
#
Expand All @@ -146,11 +149,16 @@ def scan_specs(options={})
ignore = Set[]
ignore += options[:ignore] if options[:ignore]

filter = Set[]
filter += options[:filter].map! { |current_filter| current_filter.downcase.to_sym } if options[:filter]

@lockfile.specs.each do |gem|
@database.check_gem(gem) do |advisory|
is_ignored = ignore.intersect?(advisory.identifiers.to_set)
next if is_ignored

next unless filter.empty? || filter.include?(advisory.criticality)

yield UnpatchedGem.new(gem,advisory)
end
end
Expand Down
18 changes: 18 additions & 0 deletions spec/integration_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,24 @@
end
end

context "when auditing a bundle with filtered criticality" do
let(:bundle) { 'unpatched_gems' }
let(:directory) { File.join('spec','bundle',bundle) }

let(:command) do
File.expand_path(File.join(File.dirname(__FILE__),'..','bin','bundler-audit -f medium'))
end

subject do
Dir.chdir(directory) { sh(command, :fail => true) }
end

it "should print advisories for filtered criticality" do
expect(subject).not_to include("Criticality: High")
expect(subject).to include("Criticality: Medium")
end
end

context "when auditing a bundle with insecure sources" do
let(:bundle) { 'insecure_sources' }
let(:directory) { File.join('spec','bundle',bundle) }
Expand Down
10 changes: 10 additions & 0 deletions spec/scanner_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,16 @@
expect(ids).not_to include('CVE-2013-0155')
end
end

context "when the :filter option is given" do
subject { scanner.scan(filter: ['high']) }

it "should return only filtered criticalities" do
criticalities = subject.map { |result| result.advisory.criticality }
expect(criticalities).not_to include(:medium, :low, nil)
expect(criticalities).to include(:high)
end
end
end

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

0 comments on commit ebc6516

Please sign in to comment.