Commit 685ad038 authored by Thong Kuah's avatar Thong Kuah

Merge branch '12406-vulnerabilities-to-dependency-list' into 'master'

Merge vulnerabilities data to Dependency List report

See merge request gitlab-org/gitlab-ee!14706
parents e0109d40 ff581862
---
title: Merge vulnerabilities data into Dependency List report
merge_request: 14706
author:
type: added
......@@ -11,10 +11,12 @@ module Gitlab
def parse!(json_data, report)
report_data = JSON.parse!(json_data)
report_data.fetch('dependency_files', []).each do |file|
file['dependencies'].each do |dependency|
report.add_dependency(formatter.format(dependency, file['package_manager'], file['path']))
report.add_dependency(formatter.format(dependency,
file['package_manager'],
file['path'],
report_data['vulnerabilities']))
end
end
end
......
......@@ -10,7 +10,7 @@ module Gitlab
@commit_path = ::Gitlab::Routing.url_helpers.project_blob_path(project, sha)
end
def format(dependency, package_manager, file_path)
def format(dependency, package_manager, file_path, vulnerabilities = [])
{
name: dependency['package']['name'],
packager: packager(package_manager),
......@@ -19,7 +19,8 @@ module Gitlab
blob_path: blob_path(file_path),
path: file_path
},
version: dependency['version']
version: dependency['version'],
vulnerabilities: collect_vulnerabilities(vulnerabilities, dependency, file_path)
}
end
......@@ -31,6 +32,21 @@ module Gitlab
"#{commit_path}/#{file_path}"
end
# Dependency List report is generated by dependency_scanning job.
# This is how the location is generated there
# https://gitlab.com/gitlab-org/security-products/analyzers/common/blob/a0a5074c49f34332aa3948cd9d6dc2c054cdf3a7/issue/issue.go#L169
def location(dependency, file_path)
{
"file" => file_path,
'dependency' => {
'package' => {
'name' => dependency['package']['name']
},
'version' => dependency['version']
}
}
end
def packager(package_manager)
case package_manager
when 'bundler'
......@@ -49,6 +65,14 @@ module Gitlab
package_manager
end
end
def collect_vulnerabilities(vulnerabilities, dependency, file_path)
dependency_location = location(dependency, file_path)
vulnerabilities.select do |vulnerability|
vulnerability['location'] == dependency_location
end
end
end
end
end
......
......@@ -30,6 +30,19 @@ describe Gitlab::Ci::Parsers::Security::DependencyList do
expect(report.dependencies[0][:location][:path]).to eq('rails/Gemfile.lock')
expect(report.dependencies[12][:location][:blob_path]).to eq(blob_path)
end
it 'merge vulnerabilities data' do
vuln_nokogiri = report.dependencies[1][:vulnerabilities]
vuln_debug = report.dependencies[4][:vulnerabilities]
vuln_async = report.dependencies[3][:vulnerabilities]
expect(vuln_nokogiri.size).to eq(4)
expect(vuln_nokogiri[0]['name']).to eq('Vulnerabilities in libxml2')
expect(vuln_nokogiri[0]['severity']).to eq('Unknown')
expect(vuln_debug.size).to eq(1)
expect(vuln_debug[0]['name']).to eq('Regular Expression Denial of Service')
expect(vuln_async.size).to eq(0)
end
end
context 'with old dependency scanning artifact' do
......
......@@ -19,17 +19,34 @@ describe Gitlab::Ci::Parsers::Security::Formatters::DependencyList do
let(:dependency) { parsed_report['dependency_files'][0]['dependencies'][0] }
let(:package_manager) { 'bundler' }
let(:file_path) { 'rails/Gemfile.lock' }
let(:data) { formatter.format(dependency, package_manager, file_path, parsed_report['vulnerabilities']) }
let(:blob_path) { "/#{project.full_path}/blob/#{sha}/rails/Gemfile.lock" }
it 'format report into a right format' do
data = formatter.format(dependency, package_manager, file_path)
blob_path = "/#{project.full_path}/blob/#{sha}/rails/Gemfile.lock"
context 'with secure dependency' do
let(:dependency) { parsed_report['dependency_files'][0]['dependencies'][0] }
expect(data[:name]).to eq('mini_portile2')
expect(data[:packager]).to eq('Ruby (Bundler)')
expect(data[:package_manager]).to eq('bundler')
expect(data[:location][:blob_path]).to eq(blob_path)
expect(data[:location][:path]).to eq('rails/Gemfile.lock')
expect(data[:version]).to eq('2.2.0')
it 'format report into a right format' do
expect(data[:name]).to eq('mini_portile2')
expect(data[:packager]).to eq('Ruby (Bundler)')
expect(data[:package_manager]).to eq('bundler')
expect(data[:location][:blob_path]).to eq(blob_path)
expect(data[:location][:path]).to eq('rails/Gemfile.lock')
expect(data[:version]).to eq('2.2.0')
expect(data[:vulnerabilities]).to be_empty
end
end
context 'with vulnerable dependency' do
let(:dependency) { parsed_report['dependency_files'][0]['dependencies'][1] }
it 'merge vulnerabilities data' do
vulnerabilities = data[:vulnerabilities]
expect(vulnerabilities.size).to eq(4)
expect(vulnerabilities[0]['name']).to eq('Vulnerabilities in libxml2')
expect(vulnerabilities[3]['name']).to eq('Bypass of a protection mechanism in libxslt')
expect(vulnerabilities[0]['severity']).to eq('Unknown')
end
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment