From 0b3ccd7c0e380f6dda9a5ec9c2892164962a012a Mon Sep 17 00:00:00 2001 From: Sundus Yousuf Date: Mon, 29 Oct 2018 11:02:02 -0500 Subject: [PATCH 1/3] Add option to ignore vulnerabilities by the id. (#4) * Add --ignore option to pass in list of vulnerability ids to ignore. * --ignore is a comma separated list. * Refactored the check method argumment to options hash. This was done to avoid listing all options one by one in the method argument and also RuboCop was failing for 'Avoid parameter lists longer than 5 parameters.' * Added rspec test around the --ignore option. --- lib/dependency_spy.rb | 12 ++++++++++-- lib/dependency_spy/cli.rb | 3 ++- spec/dependency_spy_spec.rb | 17 ++++++++++++++++- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/lib/dependency_spy.rb b/lib/dependency_spy.rb index 358129b..714e169 100644 --- a/lib/dependency_spy.rb +++ b/lib/dependency_spy.rb @@ -28,7 +28,14 @@ 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) + path = options[:path] || Dir.pwd + files = options[:file] + 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) @@ -65,8 +72,9 @@ 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 + if unaffected || patched || ignored false else vulnerable diff --git a/lib/dependency_spy/cli.rb b/lib/dependency_spy/cli.rb index f7a43da..591af64 100644 --- a/lib/dependency_spy/cli.rb +++ b/lib/dependency_spy/cli.rb @@ -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']) diff --git a/spec/dependency_spy_spec.rb b/spec/dependency_spy_spec.rb index 1b3393f..a4f3383 100644 --- a/spec/dependency_spy_spec.rb +++ b/spec/dependency_spy_spec.rb @@ -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 @@ -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:CVE-2017-8418' }.count + expect(select_count).to be(1) + + filtered_detected_manifests = DependencySpy::API.check({ path: 'examples', ignore: ['snykio:rubygems:rubocop:CVE-2017-8418'] }) + 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:CVE-2017-8418' }.count + expect(select_count).to be(0) + end end end From ac863ae3a4d8615b57f65ebe569a093b15ec0ebe Mon Sep 17 00:00:00 2001 From: Sundus Yousuf Date: Mon, 29 Oct 2018 13:46:08 -0500 Subject: [PATCH 2/3] Add option to ignore vulnerabilities by the id. (#4) * Fix typo. --- lib/dependency_spy.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/dependency_spy.rb b/lib/dependency_spy.rb index 714e169..c864c61 100644 --- a/lib/dependency_spy.rb +++ b/lib/dependency_spy.rb @@ -30,7 +30,7 @@ class API def self.check(options) path = options[:path] || Dir.pwd - files = options[:file] + files = options[:files] platform = options[:platform] database_path = options[:database_path] || YAVDB::Constants::DEFAULT_YAVDB_DATABASE_PATH offline = options[:offline] || false From 2e0685a24cf960faf84674cacf66abb882f1cfa4 Mon Sep 17 00:00:00 2001 From: Sundus Yousuf Date: Mon, 29 Oct 2018 13:54:20 -0500 Subject: [PATCH 3/3] Add option to ignore vulnerabilities by the id. (#4) * Fix Rubocop --- spec/dependency_spy_spec.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/dependency_spy_spec.rb b/spec/dependency_spy_spec.rb index a4f3383..ded69cc 100644 --- a/spec/dependency_spy_spec.rb +++ b/spec/dependency_spy_spec.rb @@ -18,7 +18,7 @@ RSpec.describe DependencySpy::API do describe 'check' do - detected_manifests = DependencySpy::API.check({ path: 'examples' }) + detected_manifests = DependencySpy::API.check(:path => 'examples') it 'can read all manifests inside examples' do expect(detected_manifests).to have(5).items @@ -57,7 +57,7 @@ select_count = vulnerabilities.select { |v| v.id == 'snykio:rubygems:rubocop:CVE-2017-8418' }.count expect(select_count).to be(1) - filtered_detected_manifests = DependencySpy::API.check({ path: 'examples', ignore: ['snykio:rubygems:rubocop:CVE-2017-8418'] }) + filtered_detected_manifests = DependencySpy::API.check(:path => 'examples', :ignore => ['snykio:rubygems:rubocop:CVE-2017-8418']) manifests = filtered_detected_manifests.select { |m| m.platform == 'rubygems' } dependencies = manifests.map(&:dependencies).flatten vulnerabilities = dependencies.map(&:vulnerabilities).flatten