2021-04-29 21:17:54 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
module VulnerabilityFindingHelpers
|
|
|
|
extend ActiveSupport::Concern
|
2021-11-18 22:05:49 +05:30
|
|
|
|
|
|
|
# Manually resolvable report types cannot be considered fixed once removed from the
|
|
|
|
# target branch due to requiring active triage, such as rotation of an exposed token.
|
|
|
|
REPORT_TYPES_REQUIRING_MANUAL_RESOLUTION = %w[secret_detection].freeze
|
|
|
|
|
|
|
|
def requires_manual_resolution?
|
|
|
|
REPORT_TYPES_REQUIRING_MANUAL_RESOLUTION.include?(report_type)
|
|
|
|
end
|
|
|
|
|
2021-10-27 15:23:28 +05:30
|
|
|
def matches_signatures(other_signatures, other_uuid)
|
|
|
|
other_signature_types = other_signatures.index_by(&:algorithm_type)
|
|
|
|
|
|
|
|
# highest first
|
|
|
|
match_result = nil
|
|
|
|
signatures.sort_by(&:priority).reverse_each do |signature|
|
|
|
|
matching_other_signature = other_signature_types[signature.algorithm_type]
|
|
|
|
next if matching_other_signature.nil?
|
|
|
|
|
|
|
|
match_result = matching_other_signature == signature
|
|
|
|
break
|
|
|
|
end
|
2021-04-29 21:17:54 +05:30
|
|
|
|
2021-10-27 15:23:28 +05:30
|
|
|
if match_result.nil?
|
|
|
|
[uuid, *signature_uuids].include?(other_uuid)
|
|
|
|
else
|
|
|
|
match_result
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def signature_uuids
|
|
|
|
signatures.map do |signature|
|
|
|
|
hex_sha = signature.signature_hex
|
|
|
|
::Security::VulnerabilityUUID.generate(
|
|
|
|
report_type: report_type,
|
|
|
|
location_fingerprint: hex_sha,
|
|
|
|
primary_identifier_fingerprint: primary_identifier&.fingerprint,
|
|
|
|
project_id: project_id
|
|
|
|
)
|
|
|
|
end
|
|
|
|
end
|
2022-08-13 15:12:31 +05:30
|
|
|
|
|
|
|
def build_vulnerability_finding(security_finding)
|
|
|
|
report_finding = report_finding_for(security_finding)
|
|
|
|
return Vulnerabilities::Finding.new unless report_finding
|
|
|
|
|
|
|
|
finding_data = report_finding.to_hash.except(:compare_key, :identifiers, :location, :scanner, :links, :signatures,
|
|
|
|
:flags, :evidence)
|
2023-04-23 21:23:45 +05:30
|
|
|
identifiers = report_finding.identifiers.uniq(&:fingerprint).map do |identifier|
|
2022-08-27 11:52:29 +05:30
|
|
|
Vulnerabilities::Identifier.new(identifier.to_hash.merge({ project: project }))
|
2022-08-13 15:12:31 +05:30
|
|
|
end
|
|
|
|
signatures = report_finding.signatures.map do |signature|
|
|
|
|
Vulnerabilities::FindingSignature.new(signature.to_hash)
|
|
|
|
end
|
|
|
|
evidence = Vulnerabilities::Finding::Evidence.new(data: report_finding.evidence.data) if report_finding.evidence
|
|
|
|
|
|
|
|
Vulnerabilities::Finding.new(finding_data).tap do |finding|
|
|
|
|
finding.location_fingerprint = report_finding.location.fingerprint
|
|
|
|
finding.vulnerability = vulnerability_for(security_finding.uuid)
|
|
|
|
finding.project = project
|
|
|
|
finding.sha = pipeline.sha
|
|
|
|
finding.scanner = security_finding.scanner
|
|
|
|
finding.finding_evidence = evidence
|
|
|
|
|
|
|
|
if calculate_false_positive?
|
|
|
|
finding.vulnerability_flags = report_finding.flags.map do |flag|
|
|
|
|
Vulnerabilities::Flag.new(flag)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
finding.identifiers = identifiers
|
2022-08-27 11:52:29 +05:30
|
|
|
finding.primary_identifier = identifiers.first
|
2022-08-13 15:12:31 +05:30
|
|
|
finding.signatures = signatures
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def calculate_false_positive?
|
|
|
|
project.licensed_feature_available?(:sast_fp_reduction)
|
|
|
|
end
|
2021-10-27 15:23:28 +05:30
|
|
|
end
|