Commit dcc784c4 authored by Mayra Cabrera's avatar Mayra Cabrera

Merge branch '210327-add-parsing-vendor-name' into 'master'

Add parsing vendor name from security reports

See merge request gitlab-org/gitlab!35222
parents c9387de0 37a92bfa
...@@ -11,7 +11,7 @@ module Vulnerabilities ...@@ -11,7 +11,7 @@ module Vulnerabilities
validates :project, presence: true validates :project, presence: true
validates :external_id, presence: true, uniqueness: { scope: :project_id } validates :external_id, presence: true, uniqueness: { scope: :project_id }
validates :name, presence: true validates :name, presence: true
validates :vendor, presence: true, length: { maximum: 255 } validates :vendor, length: { maximum: 255, allow_nil: false }
scope :with_external_id, -> (external_ids) { where(external_id: external_ids) } scope :with_external_id, -> (external_ids) { where(external_id: external_ids) }
end end
......
---
title: Add parsing Vendor name from Security Reports
merge_request: 35222
author:
type: added
...@@ -72,7 +72,8 @@ module Gitlab ...@@ -72,7 +72,8 @@ module Gitlab
report.add_scanner( report.add_scanner(
::Gitlab::Ci::Reports::Security::Scanner.new( ::Gitlab::Ci::Reports::Security::Scanner.new(
external_id: scanner['id'], external_id: scanner['id'],
name: scanner['name'])) name: scanner['name'],
vendor: scanner.dig('vendor', 'name')))
end end
def create_identifiers(report, identifiers) def create_identifiers(report, identifiers)
......
...@@ -61,7 +61,7 @@ module Gitlab ...@@ -61,7 +61,7 @@ module Gitlab
'severity' => severity(vulnerability['riskcode']), 'severity' => severity(vulnerability['riskcode']),
'solution' => sanitize(vulnerability['solution']), 'solution' => sanitize(vulnerability['solution']),
'confidence' => confidence(vulnerability['confidence']), 'confidence' => confidence(vulnerability['confidence']),
'scanner' => { 'id' => 'zaproxy', 'name' => 'ZAProxy' }, 'scanner' => { 'id' => 'zaproxy', 'name' => 'ZAProxy', 'vendor' => { 'name' => 'GitLab' } },
'identifiers' => [ 'identifiers' => [
{ {
'type' => 'ZAProxy_PluginId', 'type' => 'ZAProxy_PluginId',
......
...@@ -5,11 +5,12 @@ module Gitlab ...@@ -5,11 +5,12 @@ module Gitlab
module Reports module Reports
module Security module Security
class Scanner class Scanner
attr_accessor :external_id, :name attr_accessor :external_id, :name, :vendor
def initialize(external_id:, name:) def initialize(external_id:, name:, vendor:)
@external_id = external_id @external_id = external_id
@name = name @name = name
@vendor = vendor
end end
def key def key
...@@ -20,8 +21,9 @@ module Gitlab ...@@ -20,8 +21,9 @@ module Gitlab
%i[ %i[
external_id external_id
name name
vendor
].each_with_object({}) do |key, hash| ].each_with_object({}) do |key, hash|
hash[key] = public_send(key) # rubocop:disable GitlabSecurity/PublicSend hash[key] = public_send(key).to_s # rubocop:disable GitlabSecurity/PublicSend
end end
end end
......
...@@ -4,6 +4,7 @@ FactoryBot.define do ...@@ -4,6 +4,7 @@ FactoryBot.define do
factory :ci_reports_security_scanner, class: '::Gitlab::Ci::Reports::Security::Scanner' do factory :ci_reports_security_scanner, class: '::Gitlab::Ci::Reports::Security::Scanner' do
external_id { 'find_sec_bugs' } external_id { 'find_sec_bugs' }
name { 'Find Security Bugs' } name { 'Find Security Bugs' }
vendor { 'Security Scanner Vendor' }
skip_create skip_create
......
...@@ -36,7 +36,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do ...@@ -36,7 +36,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do
"cve": "CVE-1020", "cve": "CVE-1020",
"severity": "High", "severity": "High",
"solution": "Upgrade to latest version.", "solution": "Upgrade to latest version.",
"scanner": { "id": "gemnasium", "name": "Gemnasium" }, "scanner": { "id": "gemnasium", "name": "Gemnasium", "vendor": { "name": "GitLab" } },
"location": {}, "location": {},
"identifiers": [], "identifiers": [],
"links": [{ "url": "" }] "links": [{ "url": "" }]
...@@ -52,7 +52,8 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do ...@@ -52,7 +52,8 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do
"solution": "Upgrade to latest versions.", "solution": "Upgrade to latest versions.",
"scanner": { "scanner": {
"id": "gemnasium", "id": "gemnasium",
"name": "Gemnasium" "name": "Gemnasium",
"vendor": { "name": "GitLab" }
}, },
"location": {}, "location": {},
"identifiers": [], "identifiers": [],
...@@ -68,7 +69,8 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do ...@@ -68,7 +69,8 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do
"solution": "Upgrade to fixed version.\r\n", "solution": "Upgrade to fixed version.\r\n",
"scanner": { "scanner": {
"id": "gemnasium", "id": "gemnasium",
"name": "Gemnasium" "name": "Gemnasium",
"vendor": { "name": "GitLab" }
}, },
"location": {}, "location": {},
"identifiers": [], "identifiers": [],
...@@ -177,5 +179,51 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do ...@@ -177,5 +179,51 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do
end end
end end
end end
context 'parsing scanners' do
let(:raw_json) do
{
"vulnerabilities": [
{
"category": "dependency_scanning",
"name": "Vulnerabilities in libxml2",
"message": "Vulnerabilities in libxml2 in nokogiri",
"description": "",
"cve": "CVE-1020",
"severity": "High",
"solution": "Upgrade to latest version.",
"scanner": raw_scanner,
"location": {},
"identifiers": [],
"links": [{ "url": "" }]
}
],
"remediations": [],
"dependency_files": []
}
end
subject(:scanner) { report.occurrences.first.scanner }
before do
parser.parse!(raw_json.to_json, report)
end
context 'when vendor is missing in scanner' do
let(:raw_scanner) { { 'id': 'gemnasium', 'name': 'Gemnasium' } }
it 'returns scanner with empty vendor field' do
expect(scanner.vendor).to be_nil
end
end
context 'when vendor is not missing in scanner' do
let(:raw_scanner) { { 'id': 'gemnasium', 'name': 'Gemnasium', 'vendor': { 'name': 'GitLab' } } }
it 'returns scanner with parsed vendor value' do
expect(scanner.vendor).to eq('GitLab')
end
end
end
end end
end end
...@@ -33,7 +33,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Formatters::Dast do ...@@ -33,7 +33,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Formatters::Dast do
expect(vulnerability['severity']).to eq('high') expect(vulnerability['severity']).to eq('high')
expect(vulnerability['confidence']).to eq('medium') expect(vulnerability['confidence']).to eq('medium')
expect(vulnerability['solution']).to eq(sanitized_solution) expect(vulnerability['solution']).to eq(sanitized_solution)
expect(vulnerability['scanner']).to eq({ 'id' => 'zaproxy', 'name' => 'ZAProxy' }) expect(vulnerability['scanner']).to eq({ 'id' => 'zaproxy', 'name' => 'ZAProxy', 'vendor' => { 'name' => 'GitLab' } })
expect(vulnerability['links']).to eq([{ 'url' => 'http://projects.webappsec.org/Cross-Site-Request-Forgery' }, expect(vulnerability['links']).to eq([{ 'url' => 'http://projects.webappsec.org/Cross-Site-Request-Forgery' },
{ 'url' => 'http://cwe.mitre.org/data/definitions/352.html' }]) { 'url' => 'http://cwe.mitre.org/data/definitions/352.html' }])
expect(vulnerability['identifiers'][0]).to eq({ expect(vulnerability['identifiers'][0]).to eq({
......
...@@ -9,7 +9,8 @@ RSpec.describe Gitlab::Ci::Reports::Security::Scanner do ...@@ -9,7 +9,8 @@ RSpec.describe Gitlab::Ci::Reports::Security::Scanner do
let(:params) do let(:params) do
{ {
external_id: 'brakeman', external_id: 'brakeman',
name: 'Brakeman' name: 'Brakeman',
vendor: 'GitLab'
} }
end end
...@@ -19,7 +20,8 @@ RSpec.describe Gitlab::Ci::Reports::Security::Scanner do ...@@ -19,7 +20,8 @@ RSpec.describe Gitlab::Ci::Reports::Security::Scanner do
expect(subject).to have_attributes( expect(subject).to have_attributes(
external_id: 'brakeman', external_id: 'brakeman',
name: 'Brakeman' name: 'Brakeman',
vendor: 'GitLab'
) )
end end
end end
...@@ -55,7 +57,8 @@ RSpec.describe Gitlab::Ci::Reports::Security::Scanner do ...@@ -55,7 +57,8 @@ RSpec.describe Gitlab::Ci::Reports::Security::Scanner do
it 'returns expected hash' do it 'returns expected hash' do
is_expected.to eq({ is_expected.to eq({
external_id: scanner.external_id, external_id: scanner.external_id,
name: scanner.name name: scanner.name,
vendor: scanner.vendor
}) })
end end
end end
......
...@@ -15,7 +15,6 @@ RSpec.describe Vulnerabilities::Scanner do ...@@ -15,7 +15,6 @@ RSpec.describe Vulnerabilities::Scanner do
it { is_expected.to validate_presence_of(:project) } it { is_expected.to validate_presence_of(:project) }
it { is_expected.to validate_presence_of(:external_id) } it { is_expected.to validate_presence_of(:external_id) }
it { is_expected.to validate_uniqueness_of(:external_id).scoped_to(:project_id) } it { is_expected.to validate_uniqueness_of(:external_id).scoped_to(:project_id) }
it { is_expected.to validate_presence_of(:vendor) }
it { is_expected.to validate_length_of(:vendor).is_at_most(255) } it { is_expected.to validate_length_of(:vendor).is_at_most(255) }
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