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
validates :project, presence: true
validates :external_id, presence: true, uniqueness: { scope: :project_id }
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) }
end
......
---
title: Add parsing Vendor name from Security Reports
merge_request: 35222
author:
type: added
......@@ -72,7 +72,8 @@ module Gitlab
report.add_scanner(
::Gitlab::Ci::Reports::Security::Scanner.new(
external_id: scanner['id'],
name: scanner['name']))
name: scanner['name'],
vendor: scanner.dig('vendor', 'name')))
end
def create_identifiers(report, identifiers)
......
......@@ -61,7 +61,7 @@ module Gitlab
'severity' => severity(vulnerability['riskcode']),
'solution' => sanitize(vulnerability['solution']),
'confidence' => confidence(vulnerability['confidence']),
'scanner' => { 'id' => 'zaproxy', 'name' => 'ZAProxy' },
'scanner' => { 'id' => 'zaproxy', 'name' => 'ZAProxy', 'vendor' => { 'name' => 'GitLab' } },
'identifiers' => [
{
'type' => 'ZAProxy_PluginId',
......
......@@ -5,11 +5,12 @@ module Gitlab
module Reports
module Security
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
@name = name
@vendor = vendor
end
def key
......@@ -20,8 +21,9 @@ module Gitlab
%i[
external_id
name
vendor
].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
......
......@@ -4,6 +4,7 @@ FactoryBot.define do
factory :ci_reports_security_scanner, class: '::Gitlab::Ci::Reports::Security::Scanner' do
external_id { 'find_sec_bugs' }
name { 'Find Security Bugs' }
vendor { 'Security Scanner Vendor' }
skip_create
......
......@@ -36,7 +36,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do
"cve": "CVE-1020",
"severity": "High",
"solution": "Upgrade to latest version.",
"scanner": { "id": "gemnasium", "name": "Gemnasium" },
"scanner": { "id": "gemnasium", "name": "Gemnasium", "vendor": { "name": "GitLab" } },
"location": {},
"identifiers": [],
"links": [{ "url": "" }]
......@@ -52,7 +52,8 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do
"solution": "Upgrade to latest versions.",
"scanner": {
"id": "gemnasium",
"name": "Gemnasium"
"name": "Gemnasium",
"vendor": { "name": "GitLab" }
},
"location": {},
"identifiers": [],
......@@ -68,7 +69,8 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do
"solution": "Upgrade to fixed version.\r\n",
"scanner": {
"id": "gemnasium",
"name": "Gemnasium"
"name": "Gemnasium",
"vendor": { "name": "GitLab" }
},
"location": {},
"identifiers": [],
......@@ -177,5 +179,51 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do
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
......@@ -33,7 +33,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Formatters::Dast do
expect(vulnerability['severity']).to eq('high')
expect(vulnerability['confidence']).to eq('medium')
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' },
{ 'url' => 'http://cwe.mitre.org/data/definitions/352.html' }])
expect(vulnerability['identifiers'][0]).to eq({
......
......@@ -9,7 +9,8 @@ RSpec.describe Gitlab::Ci::Reports::Security::Scanner do
let(:params) do
{
external_id: 'brakeman',
name: 'Brakeman'
name: 'Brakeman',
vendor: 'GitLab'
}
end
......@@ -19,7 +20,8 @@ RSpec.describe Gitlab::Ci::Reports::Security::Scanner do
expect(subject).to have_attributes(
external_id: 'brakeman',
name: 'Brakeman'
name: 'Brakeman',
vendor: 'GitLab'
)
end
end
......@@ -55,7 +57,8 @@ RSpec.describe Gitlab::Ci::Reports::Security::Scanner do
it 'returns expected hash' do
is_expected.to eq({
external_id: scanner.external_id,
name: scanner.name
name: scanner.name,
vendor: scanner.vendor
})
end
end
......
......@@ -15,7 +15,6 @@ RSpec.describe Vulnerabilities::Scanner do
it { is_expected.to validate_presence_of(:project) }
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_presence_of(:vendor) }
it { is_expected.to validate_length_of(:vendor).is_at_most(255) }
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