Commit 1672ec35 authored by Olivier Gonzalez's avatar Olivier Gonzalez

Add package name to dependency scanning reports

Generate specific location fingerprint per report type
Make metadata version dynamic and guess it based on content
parent ac44c83a
......@@ -7,8 +7,8 @@ module Gitlab
ParserNotFoundError = Class.new(StandardError)
PARSERS = {
sast: ::Gitlab::Ci::Parsers::Security::Common,
dependency_scanning: ::Gitlab::Ci::Parsers::Security::Common
sast: ::Gitlab::Ci::Parsers::Security::Sast,
dependency_scanning: ::Gitlab::Ci::Parsers::Security::DependencyScanning
}.freeze
def self.fabricate!(file_type)
......
......@@ -7,8 +7,6 @@ module Gitlab
class Common
SecurityReportParserError = Class.new(StandardError)
METADATA_VERSION = '1.2'
def parse!(json_data, report)
vulnerabilities = JSON.parse!(json_data)
......@@ -41,7 +39,7 @@ module Gitlab
raw_metadata: data.to_json,
# Version is hardcoded here untill provided in the report.
# See https://gitlab.com/gitlab-org/gitlab-ee/issues/8025
metadata_version: METADATA_VERSION
metadata_version: metadata_version(data)
)
end
......@@ -80,10 +78,6 @@ module Gitlab
input.blank? ? 'undefined' : input.downcase
end
def generate_location_fingerprint(location)
Digest::SHA1.hexdigest("#{location['file']}:#{location['start_line']}:#{location['end_line']}")
end
def generate_project_fingerprint(compare_key)
Digest::SHA1.hexdigest(compare_key)
end
......
# frozen_string_literal: true
module Gitlab
module Ci
module Parsers
module Security
class DependencyScanning < Common
private
def metadata_version(vulnerability)
'1.3'
end
def generate_location_fingerprint(location)
Digest::SHA1.hexdigest("#{location['file']}:#{location['dependency']['package']['name']}")
end
end
end
end
end
end
# frozen_string_literal: true
module Gitlab
module Ci
module Parsers
module Security
class Sast < Common
private
def metadata_version(vulnerability)
'1.2'
end
def generate_location_fingerprint(location)
Digest::SHA1.hexdigest("#{location['file']}:#{location['start_line']}:#{location['end_line']}")
end
end
end
end
end
end
......@@ -2,10 +2,11 @@
require 'spec_helper'
describe Gitlab::Ci::Parsers::Security::Common do
describe Gitlab::Ci::Parsers::Security::DependencyScanning do
describe '#parse!' do
let(:project) { artifact.project }
let(:pipeline) { artifact.job.pipeline }
let(:artifact) { create(:ee_ci_job_artifact, :dependency_scanning) }
let(:report) { Gitlab::Ci::Reports::Security::Report.new(artifact.file_type) }
let(:parser) { described_class.new }
......@@ -15,24 +16,18 @@ describe Gitlab::Ci::Parsers::Security::Common do
end
end
context 'sast report' do
let(:artifact) { create(:ee_ci_job_artifact, :sast) }
it "parses all identifiers and occurrences" do
expect(report.occurrences.length).to eq(3)
expect(report.identifiers.length).to eq(4)
expect(report.scanners.length).to eq(3)
end
end
context 'dependency_scanning report' do
let(:artifact) { create(:ee_ci_job_artifact, :dependency_scanning) }
it "parses all identifiers and occurrences" do
expect(report.occurrences.length).to eq(4)
expect(report.identifiers.length).to eq(7)
expect(report.scanners.length).to eq(2)
end
it "generates expected location fingerprint" do
expect(report.occurrences.first[:location_fingerprint]).to eq('2773f8cc955346ab1f756b94aa310db8e17c0944')
end
it "generates expected metadata_version" do
expect(report.occurrences.first[:metadata_version]).to eq('1.3')
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Gitlab::Ci::Parsers::Security::Sast do
describe '#parse!' do
let(:project) { artifact.project }
let(:pipeline) { artifact.job.pipeline }
let(:artifact) { create(:ee_ci_job_artifact, :sast) }
let(:report) { Gitlab::Ci::Reports::Security::Report.new(artifact.file_type) }
let(:parser) { described_class.new }
before do
artifact.each_blob do |blob|
parser.parse!(blob, report)
end
end
it "parses all identifiers and occurrences" do
expect(report.occurrences.length).to eq(3)
expect(report.identifiers.length).to eq(4)
expect(report.scanners.length).to eq(3)
end
it "generates expected location fingerprint" do
expect(report.occurrences.first[:location_fingerprint]).to eq('6b6bb283d43cc510d7d1e73e2882b3652cb34bd5')
end
it "generates expected metadata_version" do
expect(report.occurrences.first[:metadata_version]).to eq('1.2')
end
end
end
......@@ -11,7 +11,13 @@
"name": "Gemnasium"
},
"location": {
"file": "app/pom.xml"
"file": "app/pom.xml",
"dependency": {
"package": {
"name": "io.netty/netty"
},
"version": "3.9.1.Final"
}
},
"identifiers": [
{
......@@ -55,7 +61,13 @@
"name": "Gemnasium"
},
"location": {
"file": "app/requirements.txt"
"file": "app/requirements.txt",
"dependency": {
"package": {
"name": "Django"
},
"version": "1.11.3"
}
},
"identifiers": [
{
......@@ -93,7 +105,13 @@
"name": "Gemnasium"
},
"location": {
"file": "rails/Gemfile.lock"
"file": "rails/Gemfile.lock",
"dependency": {
"package": {
"name": "nokogiri"
},
"version": "1.8.0"
}
},
"identifiers": [
{
......@@ -131,7 +149,13 @@
"name": "bundler-audit"
},
"location": {
"file": "sast-sample-rails/Gemfile.lock"
"file": "sast-sample-rails/Gemfile.lock",
"dependency": {
"package": {
"name": "ffi"
},
"version": "1.9.18"
}
},
"identifiers": [
{
......
......@@ -11,7 +11,13 @@
"name": "Gemnasium"
},
"location": {
"file": "app/pom.xml"
"file": "app/pom.xml",
"dependency": {
"package": {
"name": "io.netty/netty"
},
"version": "3.9.1.Final"
}
},
"identifiers": [
{
......@@ -55,7 +61,13 @@
"name": "Gemnasium"
},
"location": {
"file": "app/requirements.txt"
"file": "app/requirements.txt",
"dependency": {
"package": {
"name": "Django"
},
"version": "1.11.3"
}
},
"identifiers": [
{
......@@ -93,7 +105,13 @@
"name": "Gemnasium"
},
"location": {
"file": "rails/Gemfile.lock"
"file": "rails/Gemfile.lock",
"dependency": {
"package": {
"name": "nokogiri"
},
"version": "1.8.0"
}
},
"identifiers": [
{
......@@ -131,7 +149,13 @@
"name": "bundler-audit"
},
"location": {
"file": "sast-sample-rails/Gemfile.lock"
"file": "sast-sample-rails/Gemfile.lock",
"dependency": {
"package": {
"name": "ffi"
},
"version": "1.9.18"
}
},
"identifiers": [
{
......
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