debian-mirror-gitlab/lib/gitlab/ci/reports/security/finding.rb

154 lines
4.8 KiB
Ruby
Raw Normal View History

2021-10-27 15:23:28 +05:30
# frozen_string_literal: true
module Gitlab
module Ci
module Reports
module Security
class Finding
include ::VulnerabilityFindingHelpers
attr_reader :compare_key
attr_reader :confidence
attr_reader :identifiers
2021-11-11 11:23:49 +05:30
attr_reader :flags
2021-10-27 15:23:28 +05:30
attr_reader :links
attr_reader :location
attr_reader :metadata_version
attr_reader :name
attr_reader :old_location
attr_reader :project_fingerprint
attr_reader :raw_metadata
attr_reader :report_type
attr_reader :scanner
attr_reader :scan
attr_reader :severity
attr_accessor :uuid
attr_accessor :overridden_uuid
attr_reader :remediations
attr_reader :details
attr_reader :signatures
attr_reader :project_id
delegate :file_path, :start_line, :end_line, to: :location
2021-11-11 11:23:49 +05:30
def initialize(compare_key:, identifiers:, flags: [], links: [], remediations: [], location:, metadata_version:, name:, raw_metadata:, report_type:, scanner:, scan:, uuid:, confidence: nil, severity: nil, details: {}, signatures: [], project_id: nil, vulnerability_finding_signatures_enabled: false) # rubocop:disable Metrics/ParameterLists
2021-10-27 15:23:28 +05:30
@compare_key = compare_key
@confidence = confidence
@identifiers = identifiers
2021-11-11 11:23:49 +05:30
@flags = flags
2021-10-27 15:23:28 +05:30
@links = links
@location = location
@metadata_version = metadata_version
@name = name
@raw_metadata = raw_metadata
@report_type = report_type
@scanner = scanner
@scan = scan
@severity = severity
@uuid = uuid
@remediations = remediations
@details = details
@signatures = signatures
@project_id = project_id
@vulnerability_finding_signatures_enabled = vulnerability_finding_signatures_enabled
@project_fingerprint = generate_project_fingerprint
end
def to_hash
%i[
compare_key
confidence
identifiers
2021-11-11 11:23:49 +05:30
flags
2021-10-27 15:23:28 +05:30
links
location
metadata_version
name
project_fingerprint
raw_metadata
report_type
scanner
scan
severity
uuid
details
signatures
].each_with_object({}) do |key, hash|
hash[key] = public_send(key) # rubocop:disable GitlabSecurity/PublicSend
end
end
def primary_identifier
identifiers.first
end
def update_location(new_location)
@old_location = location
@location = new_location
end
def unsafe?(severity_levels)
severity.in?(severity_levels)
end
def eql?(other)
return false unless report_type == other.report_type && primary_identifier_fingerprint == other.primary_identifier_fingerprint
if @vulnerability_finding_signatures_enabled
matches_signatures(other.signatures, other.uuid)
else
location.fingerprint == other.location.fingerprint
end
end
def hash
if @vulnerability_finding_signatures_enabled && !signatures.empty?
highest_signature = signatures.max_by(&:priority)
report_type.hash ^ highest_signature.signature_hex.hash ^ primary_identifier_fingerprint.hash
else
report_type.hash ^ location.fingerprint.hash ^ primary_identifier_fingerprint.hash
end
end
def valid?
scanner.present? && primary_identifier.present? && location.present? && uuid.present?
end
def keys
@keys ||= identifiers.reject(&:type_identifier?).map do |identifier|
FindingKey.new(location_fingerprint: location&.fingerprint, identifier_fingerprint: identifier.fingerprint)
end
end
def primary_identifier_fingerprint
primary_identifier&.fingerprint
end
def <=>(other)
if severity == other.severity
compare_key <=> other.compare_key
else
::Enums::Vulnerability.severity_levels[other.severity] <=>
::Enums::Vulnerability.severity_levels[severity]
end
end
def scanner_order_to(other)
return 1 unless scanner
return -1 unless other&.scanner
scanner <=> other.scanner
end
private
def generate_project_fingerprint
Digest::SHA1.hexdigest(compare_key)
end
end
end
end
end
end