Commit cededed8 authored by Alan (Maciej) Paruszewski's avatar Alan (Maciej) Paruszewski Committed by Bob Van Landuyt

Add parsing details from security reports

This change adds parsing new field from security report and saving it
into newly created column in vulnerability findings.
parent 90f18823
{ {
"type": "object", "type": "object",
"description": "The schema for vulnerability finding details", "description": "The schema for vulnerability finding details",
"additionalProperties": false "additionalProperties": false,
"patternProperties": {
"^.*$": {
"allOf": [
{ "$ref": "#/definitions/named_field" },
{ "$ref": "#/definitions/type_list" }
]
}
},
"definitions": {
"type_list": {
"oneOf": [
{ "$ref": "#/definitions/named_list" },
{ "$ref": "#/definitions/list" },
{ "$ref": "#/definitions/table" },
{ "$ref": "#/definitions/text" },
{ "$ref": "#/definitions/url" },
{ "$ref": "#/definitions/code" },
{ "$ref": "#/definitions/int" },
{ "$ref": "#/definitions/commit" },
{ "$ref": "#/definitions/file_location" },
{ "$ref": "#/definitions/module_location" }
]
},
"lang_text": {
"type": "object",
"required": [ "value", "lang" ],
"properties": {
"lang": { "type": "string" },
"value": { "type": "string" }
}
},
"lang_text_list": {
"type": "array",
"items": { "$ref": "#/definitions/lang_text" }
},
"named_field": {
"type": "object",
"required": [ "name" ],
"properties": {
"name": { "$ref": "#/definitions/lang_text_list" },
"description": { "$ref": "#/definitions/lang_text_list" }
}
},
"named_list": {
"type": "object",
"description": "An object with named and typed fields",
"required": [ "type", "items" ],
"properties": {
"type": { "const": "named-list" },
"items": {
"type": "object",
"patternProperties": {
"^.*$": {
"allOf": [
{ "$ref": "#/definitions/named_field" },
{ "$ref": "#/definitions/type_list" }
]
}
}
}
}
},
"list": {
"type": "object",
"description": "A list of typed fields",
"required": [ "type", "items" ],
"properties": {
"type": { "const": "list" },
"items": {
"type": "array",
"items": { "$ref": "#/definitions/type_list" }
}
}
},
"table": {
"type": "object",
"description": "A table of typed fields",
"required": [],
"properties": {
"type": { "const": "table" },
"items": {
"type": "object",
"properties": {
"header": {
"type": "array",
"items": {
"$ref": "#/definitions/type_list"
}
},
"rows": {
"type": "array",
"items": {
"type": "array",
"items": {
"$ref": "#/definitions/type_list"
}
}
}
}
}
}
},
"text": {
"type": "object",
"description": "Raw text",
"required": [ "type", "value" ],
"properties": {
"type": { "const": "text" },
"value": { "$ref": "#/definitions/lang_text_list" }
}
},
"url": {
"type": "object",
"description": "A single URL",
"required": [ "type", "href" ],
"properties": {
"type": { "const": "url" },
"text": { "$ref": "#/definitions/lang_text_list" },
"href": { "type": "string" }
}
},
"code": {
"type": "object",
"description": "A codeblock",
"required": [ "type", "value" ],
"properties": {
"type": { "const": "code" },
"value": { "type": "string" },
"lang": { "type": "string" }
}
},
"int": {
"type": "object",
"description": "An integer",
"required": [ "type", "value" ],
"properties": {
"type": { "const": "int" },
"value": { "type": "integer" },
"format": {
"type": "string",
"enum": [ "default", "hex" ]
}
}
},
"commit": {
"type": "object",
"description": "A specific commit within the project",
"required": [ "type", "value" ],
"properties": {
"type": { "const": "commit" },
"value": { "type": "string", "description": "The commit SHA" }
}
},
"file_location": {
"type": "object",
"description": "A location within a file in the project",
"required": [ "type", "file_name", "line_start" ],
"properties": {
"type": { "const": "file-location" },
"file_name": { "type": "string" },
"line_start": { "type": "integer" },
"line_end": { "type": "integer" }
}
},
"module_location": {
"type": "object",
"description": "A location within a binary module of the form module+relative_offset",
"required": [ "type", "module_name", "offset" ],
"properties": {
"type": { "const": "module-location" },
"module_name": { "type": "string" },
"offset": { "type": "integer" }
}
}
}
} }
---
title: Add parsing details from security reports
merge_request: 49107
author:
type: added
...@@ -74,7 +74,8 @@ module Gitlab ...@@ -74,7 +74,8 @@ module Gitlab
links: links, links: links,
remediations: remediations, remediations: remediations,
raw_metadata: data.to_json, raw_metadata: data.to_json,
metadata_version: version)) metadata_version: version,
details: data['details'] || {}))
end end
def create_scan(report, scan_data) def create_scan(report, scan_data)
......
...@@ -23,10 +23,11 @@ module Gitlab ...@@ -23,10 +23,11 @@ module Gitlab
attr_reader :severity attr_reader :severity
attr_reader :uuid attr_reader :uuid
attr_reader :remediations attr_reader :remediations
attr_reader :details
delegate :file_path, :start_line, :end_line, to: :location delegate :file_path, :start_line, :end_line, to: :location
def initialize(compare_key:, identifiers:, links: [], remediations: [], location:, metadata_version:, name:, raw_metadata:, report_type:, scanner:, scan:, uuid:, confidence: nil, severity: nil) # rubocop:disable Metrics/ParameterLists def initialize(compare_key:, identifiers:, links: [], remediations: [], location:, metadata_version:, name:, raw_metadata:, report_type:, scanner:, scan:, uuid:, confidence: nil, severity: nil, details: {}) # rubocop:disable Metrics/ParameterLists
@compare_key = compare_key @compare_key = compare_key
@confidence = confidence @confidence = confidence
@identifiers = identifiers @identifiers = identifiers
...@@ -41,6 +42,7 @@ module Gitlab ...@@ -41,6 +42,7 @@ module Gitlab
@severity = severity @severity = severity
@uuid = uuid @uuid = uuid
@remediations = remediations @remediations = remediations
@details = details
@project_fingerprint = generate_project_fingerprint @project_fingerprint = generate_project_fingerprint
end end
...@@ -61,6 +63,7 @@ module Gitlab ...@@ -61,6 +63,7 @@ module Gitlab
scan scan
severity severity
uuid uuid
details
].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) # rubocop:disable GitlabSecurity/PublicSend
end end
......
...@@ -18,7 +18,25 @@ ...@@ -18,7 +18,25 @@
{ {
"url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1020" "url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1020"
} }
] ],
"details": {
"commit": {
"name": [
{
"lang": "en",
"value": "The Commit"
}
],
"description": [
{
"lang": "en",
"value": "Commit where the vulnerability was identified"
}
],
"type": "commit",
"value": "41df7b7eb3be2b5be2c406c2f6d28cd6631eeb19"
}
}
}, },
{ {
"id": "bb2fbeb1b71ea360ce3f86f001d4e84823c3ffe1a1f7d41ba7466b14cfa953d3", "id": "bb2fbeb1b71ea360ce3f86f001d4e84823c3ffe1a1f7d41ba7466b14cfa953d3",
......
...@@ -65,6 +65,26 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do ...@@ -65,6 +65,26 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do
end end
end end
context 'parsing finding.details' do
let(:artifact) { build(:ee_ci_job_artifact, :common_security_report) }
context 'when details are provided' do
it 'sets details from the report' do
vulnerability = report.findings.find { |x| x.compare_key == 'CVE-1020' }
expected_details = Gitlab::Json.parse(vulnerability.raw_metadata)['details']
expect(vulnerability.details).to eq(expected_details)
end
end
context 'when details are not provided' do
it 'sets empty hash' do
vulnerability = report.findings.find { |x| x.compare_key == 'CVE-1030' }
expect(vulnerability.details).to eq({})
end
end
end
context 'parsing remediations' do context 'parsing remediations' do
let(:expected_remediation) { create(:ci_reports_security_remediation, diff: '') } let(:expected_remediation) { create(:ci_reports_security_remediation, diff: '') }
......
...@@ -30,7 +30,25 @@ RSpec.describe Gitlab::Ci::Reports::Security::Finding do ...@@ -30,7 +30,25 @@ RSpec.describe Gitlab::Ci::Reports::Security::Finding do
scanner: scanner, scanner: scanner,
scan: nil, scan: nil,
severity: :high, severity: :high,
uuid: 'cadf8cf0a8228fa92a0f4897a0314083bb38' uuid: 'cadf8cf0a8228fa92a0f4897a0314083bb38',
details: {
'commit' => {
'name' => [
{
'lang' => 'en',
'value' => 'The Commit'
}
],
'description' => [
{
'lang' => 'en',
'value' => 'Commit where the vulnerability was identified'
}
],
'type' => 'commit',
'value' => '41df7b7eb3be2b5be2c406c2f6d28cd6631eeb19'
}
}
} }
end end
...@@ -52,7 +70,25 @@ RSpec.describe Gitlab::Ci::Reports::Security::Finding do ...@@ -52,7 +70,25 @@ RSpec.describe Gitlab::Ci::Reports::Security::Finding do
report_type: :sast, report_type: :sast,
scanner: scanner, scanner: scanner,
severity: :high, severity: :high,
uuid: 'cadf8cf0a8228fa92a0f4897a0314083bb38' uuid: 'cadf8cf0a8228fa92a0f4897a0314083bb38',
details: {
'commit' => {
'name' => [
{
'lang' => 'en',
'value' => 'The Commit'
}
],
'description' => [
{
'lang' => 'en',
'value' => 'Commit where the vulnerability was identified'
}
],
'type' => 'commit',
'value' => '41df7b7eb3be2b5be2c406c2f6d28cd6631eeb19'
}
}
) )
end end
end end
...@@ -100,7 +136,8 @@ RSpec.describe Gitlab::Ci::Reports::Security::Finding do ...@@ -100,7 +136,8 @@ RSpec.describe Gitlab::Ci::Reports::Security::Finding do
scanner: occurrence.scanner, scanner: occurrence.scanner,
scan: occurrence.scan, scan: occurrence.scan,
severity: occurrence.severity, severity: occurrence.severity,
uuid: occurrence.uuid uuid: occurrence.uuid,
details: occurrence.details
}) })
end 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