Skip to content
This repository has been archived by the owner on Jul 24, 2021. It is now read-only.

Commit

Permalink
Merge pull request #14 from rtfpessoa/sundus-y-master
Browse files Browse the repository at this point in the history
Add option to ignore vulnerabilities by the id
  • Loading branch information
rtfpessoa authored Jul 3, 2019
2 parents fe53b7d + f0d6625 commit e719b65
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 31 deletions.
44 changes: 26 additions & 18 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
dependency_spy (0.4.1)
dependency_spy (0.5.0)
bibliothecary (~> 6.6)
colorize (= 0.8.1)
semantic_range (~> 2.2)
Expand All @@ -13,12 +13,14 @@ GEM
specs:
ansi (1.5.0)
ast (2.4.0)
bibliothecary (6.6.0)
bibliothecary (6.7.3)
commander
deb_control
librariesio-gem-parser
ox (>= 2.8.1)
sdl4r
strings
strings-ansi
toml-rb (~> 1.0)
typhoeus
citrus (3.0.2)
Expand All @@ -29,21 +31,21 @@ GEM
highline (~> 2.0.0)
deb_control (0.0.1)
diff-lcs (1.3)
docile (1.3.1)
docile (1.3.2)
ethon (0.12.0)
ffi (>= 1.3.0)
execjs (2.7.0)
ffi (1.11.0)
ffi (1.11.1)
highline (2.0.2)
jaro_winkler (1.5.2)
jaro_winkler (1.5.3)
json (2.2.0)
kramdown (1.17.0)
kramdown (2.1.0)
librariesio-gem-parser (1.0.0)
libv8 (3.16.14.19-x86_64-linux)
oga (2.15)
ast
ruby-ll (~> 2.1)
ox (2.10.0)
ox (2.11.0)
parallel (1.17.0)
parser (2.6.3.0)
ast (~> 2.4.0)
Expand All @@ -56,16 +58,16 @@ GEM
rspec-mocks (~> 3.8.0)
rspec-collection_matchers (1.1.3)
rspec-expectations (>= 2.99.0.beta1)
rspec-core (3.8.0)
rspec-core (3.8.2)
rspec-support (~> 3.8.0)
rspec-expectations (3.8.3)
rspec-expectations (3.8.4)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0)
rspec-mocks (3.8.0)
rspec-mocks (3.8.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.8.0)
rspec-support (3.8.0)
rubocop (0.69.0)
rspec-support (3.8.2)
rubocop (0.72.0)
jaro_winkler (~> 1.5.1)
parallel (~> 1.10)
parser (>= 2.6)
Expand All @@ -77,15 +79,20 @@ GEM
ruby-ll (2.1.2)
ansi
ast
ruby-progressbar (1.10.0)
ruby-progressbar (1.10.1)
sdl4r (0.9.11)
semantic_interval (0.1.0)
semantic_range (2.2.1)
simplecov (0.16.1)
simplecov (0.17.0)
docile (~> 1.1)
json (>= 1.8, < 3)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.2)
strings (0.1.5)
strings-ansi (~> 0.1)
unicode-display_width (~> 1.5)
unicode_utils (~> 1.4)
strings-ansi (0.1.0)
therubyracer (0.12.3)
libv8 (~> 3.16.14.15)
ref
Expand All @@ -95,10 +102,11 @@ GEM
typhoeus (1.3.1)
ethon (>= 0.9.0)
unicode-display_width (1.6.0)
yavdb (0.5.1)
execjs (~> 2.7.0)
json (~> 2.1)
kramdown (~> 1.17)
unicode_utils (1.4.0)
yavdb (0.5.2)
execjs (~> 2.7)
json (~> 2.2)
kramdown (~> 2.1)
oga (~> 2.15)
semantic_interval (~> 0.1)
therubyracer (~> 0.12)
Expand Down
16 changes: 14 additions & 2 deletions lib/dependency_spy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,20 @@
module DependencySpy
class API

def self.check(path = Dir.pwd, files = nil, platform = nil, database_path = YAVDB::Constants::DEFAULT_YAVDB_DATABASE_PATH, offline = false)
def self.check(options)
verbose = options[:verbose]
path = options[:path] || Dir.pwd
files = options[:files]
platform = options[:platform]
database_path = options[:database_path] || YAVDB::Constants::DEFAULT_YAVDB_DATABASE_PATH
offline = options[:offline] || false
ignore = options[:ignore] || []

if !File.exist?(database_path) && offline
puts 'No local database found. Cannot obtain database since offline mode is enabled.'
exit(10)
elsif !offline
puts 'Going to update the local vulnerability database.'
puts 'Going to update the local vulnerability database.' if verbose
YAVDB::API.download_database(false, YAVDB::Constants::DEFAULT_YAVDB_PATH)
end

Expand Down Expand Up @@ -64,9 +72,13 @@ def self.check(path = Dir.pwd, files = nil, platform = nil, database_path = YAVD
vulnerable = vuln.vulnerable_versions ? vuln.vulnerable_versions.any? { |vv| DependencySpy::SemVer.intersects(vv, version) } : false
unaffected = vuln.unaffected_versions ? vuln.unaffected_versions.any? { |vu| DependencySpy::SemVer.intersects(vu, version) } : false
patched = vuln.patched_versions ? vuln.patched_versions.any? { |vp| DependencySpy::SemVer.intersects(vp, version) } : false
ignored = ignore.include?(vuln.id)

if unaffected || patched
false
elsif ignored
puts "Skipping ignored vulnerability with #{vuln.id}." if verbose
false
else
vulnerable
end
Expand Down
3 changes: 2 additions & 1 deletion lib/dependency_spy/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ class CLI < Thor
method_option('offline', :type => :boolean, :default => false)
method_option('severity-threshold', :aliases => :s, :type => :string, :enum => YAVDB::Constants::SEVERITIES, :default => 'low')
method_option('with-color', :type => :boolean, :default => true)
method_option('ignore', :aliases => :i, :type => :array, :default => [])
def check
manifests = API.check(options['path'], options['files'], options['platform'], options['database-path'], options['offline'])
manifests = API.check(options)

formatted_output = if (options['formatter'] == 'text') && !options['output-path'] && options['with-color']
DependencySpy::Formatters::Text.format(manifests, options['severity-threshold'])
Expand Down
2 changes: 1 addition & 1 deletion lib/dependency_spy/formatters/json.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def self.format(manifests)

filtered_manifests
.reject { |m| m[:dependencies].nil? }
.map(&:to_json)
.to_json
end

end
Expand Down
12 changes: 7 additions & 5 deletions lib/dependency_spy/formatters/text.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,15 @@ def self.format(manifests, severity_threshold = nil)

package_header = " Vulnerable: #{package.name}/#{package.type}:#{package.version}"
package_body = package.vulnerabilities.map do |vuln|
first = " Title: #{vuln.title}\n"
second = " Severity: #{(vuln.severity || 'unknown').capitalize}\n"
third = " Source: #{vuln.source_url}\n\n"
body = ''
body += " Title: #{vuln.title}\n"
body += " Severity: #{(vuln.severity || 'unknown').capitalize}\n"
body += " Source: #{vuln.source_url}\n"
body += " Identifier: #{vuln.id}\n\n"
if severity_threshold && DependencySpy::Helper.severity_above_threshold?(vuln.severity, severity_threshold)
"#{first}#{second}#{third}".red
body.red
else
"#{first}#{second}#{third}"
body
end
end

Expand Down
2 changes: 1 addition & 1 deletion lib/dependency_spy/formatters/yaml.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def self.format(manifests)

filtered_manifests
.reject { |m| m[:dependencies].nil? }
.map(&:to_json)
.to_yaml
end

end
Expand Down
2 changes: 1 addition & 1 deletion lib/dependency_spy/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@

module DependencySpy

VERSION = '0.4.1'
VERSION = '0.5.0'

end
19 changes: 17 additions & 2 deletions spec/dependency_spy_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

RSpec.describe DependencySpy::API do
describe 'check' do
detected_manifests = DependencySpy::API.check('examples')
detected_manifests = DependencySpy::API.check(:path => 'examples')

it 'can read all manifests inside examples' do
expect(detected_manifests).to have(5).items
Expand All @@ -34,7 +34,7 @@
manifests = detected_manifests.select { |m| m.platform == 'npm' }
dependencies = manifests.map(&:dependencies).flatten
vulnerabilities = dependencies.map(&:vulnerabilities).flatten
expect(vulnerabilities).to have(118).items
expect(vulnerabilities).to have(121).items
end

it 'can read all dependencies for rubygems manifest' do
Expand All @@ -49,5 +49,20 @@
vulnerabilities = dependencies.map(&:vulnerabilities).flatten
expect(vulnerabilities).to have(3).items
end

it 'can ignore vulnerabilities by id' do
manifests = detected_manifests.select { |m| m.platform == 'rubygems' }
dependencies = manifests.map(&:dependencies).flatten
vulnerabilities = dependencies.map(&:vulnerabilities).flatten
select_count = vulnerabilities.select { |v| v.id == 'snykio:rubygems:rubocop:20447' }.count
expect(select_count).to eq(1)

filtered_detected_manifests = DependencySpy::API.check(:path => 'examples', :ignore => ['snykio:rubygems:rubocop:20447'])
manifests = filtered_detected_manifests.select { |m| m.platform == 'rubygems' }
dependencies = manifests.map(&:dependencies).flatten
vulnerabilities = dependencies.map(&:vulnerabilities).flatten
select_count = vulnerabilities.select { |v| v.id == 'snykio:rubygems:rubocop:20447' }.count
expect(select_count).to eq(0)
end
end
end

0 comments on commit e719b65

Please sign in to comment.