Skip to content
Snippets Groups Projects
Commit b4f90532 authored by James Johnson's avatar James Johnson
Browse files

Uses stored finding fingerprints during vuln mgmt

* Updates the `eql?` method on Finding objects
* Adds FindingFingerprint model and PORO models
* Adds feature flag :vulnerability_finding_fingerprints
* Uses `Finding.uuid` field to correlate findings with feedbacks
* Adds `Finding.uuid` to the vulnerability_occurrences UNIQUE index
* Adds changelog for using vulnerability fingerprints
parent 4ca14b2c
No related branches found
No related tags found
No related merge requests found
Showing
with 386 additions and 53 deletions
# frozen_string_literal: true
# See https://docs.gitlab.com/ee/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddUuidToVulnerabilityOccurrencesUniqueIndex < ActiveRecord::Migration[6.0]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
INDEX_NAME = 'index_vulnerability_occurrences_on_unique_keys'
disable_ddl_transaction!
def up
remove_concurrent_index_by_name(:vulnerability_occurrences, INDEX_NAME)
add_concurrent_index(
:vulnerability_occurrences,
[:project_id, :primary_identifier_id, :location_fingerprint, :scanner_id, :uuid],
name: INDEX_NAME
)
end
def down
remove_concurrent_index_by_name(:vulnerability_occurrences, INDEX_NAME)
add_concurrent_index(
:vulnerability_occurrences,
[:project_id, :primary_identifier_id, :location_fingerprint, :scanner_id],
name: INDEX_NAME
)
end
end
433d47e2526ea08d0575b158de57e76fd69862316a6e804d95c716e1eec2439f
\ No newline at end of file
Loading
Loading
@@ -23745,7 +23745,7 @@ CREATE INDEX index_vulnerability_occurrences_on_project_fingerprint ON vulnerabi
 
CREATE INDEX index_vulnerability_occurrences_on_scanner_id ON vulnerability_occurrences USING btree (scanner_id);
 
CREATE UNIQUE INDEX index_vulnerability_occurrences_on_unique_keys ON vulnerability_occurrences USING btree (project_id, primary_identifier_id, location_fingerprint, scanner_id);
CREATE INDEX index_vulnerability_occurrences_on_unique_keys ON vulnerability_occurrences USING btree (project_id, primary_identifier_id, location_fingerprint, scanner_id, uuid);
 
CREATE UNIQUE INDEX index_vulnerability_occurrences_on_uuid ON vulnerability_occurrences USING btree (uuid);
 
Loading
Loading
@@ -47,10 +47,13 @@ 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)
finding_data = report_finding.to_hash.except(:compare_key, :identifiers, :location, :scanner, :links, :fingerprints)
identifiers = report_finding.identifiers.map do |identifier|
Vulnerabilities::Identifier.new(identifier.to_hash)
end
fingerprints = report_finding.fingerprints.map do |fingerprint|
Vulnerabilities::FindingFingerprint.new(fingerprint.to_hash)
end
 
Vulnerabilities::Finding.new(finding_data).tap do |finding|
finding.location_fingerprint = report_finding.location.fingerprint
Loading
Loading
@@ -59,6 +62,7 @@ def build_vulnerability_finding(security_finding)
finding.sha = pipeline.sha
finding.scanner = security_finding.scanner
finding.identifiers = identifiers
finding.fingerprints = fingerprints
end
end
 
Loading
Loading
Loading
Loading
@@ -75,7 +75,7 @@ def vulnerabilities_by_finding_fingerprint(report_type, report)
def normalize_report_findings(report_findings, vulnerabilities)
report_findings.map do |report_finding|
finding_hash = report_finding.to_hash
.except(:compare_key, :identifiers, :location, :scanner, :links)
.except(:compare_key, :identifiers, :location, :scanner, :links, :fingerprints)
 
finding = Vulnerabilities::Finding.new(finding_hash)
# assigning Vulnerabilities to Findings to enable the computed state
Loading
Loading
@@ -84,12 +84,16 @@ def normalize_report_findings(report_findings, vulnerabilities)
finding.project = pipeline.project
finding.sha = pipeline.sha
finding.build_scanner(report_finding.scanner&.to_hash)
# finding.location = report_finding.location_json
finding.finding_links = report_finding.links.map do |link|
Vulnerabilities::FindingLink.new(link.to_hash)
end
finding.identifiers = report_finding.identifiers.map do |identifier|
Vulnerabilities::Identifier.new(identifier.to_hash)
end
finding.fingerprints = report_finding.fingerprints.map do |fingerprint|
Vulnerabilities::FindingFingerprint.new(fingerprint.to_hash)
end
 
finding
end
Loading
Loading
@@ -111,6 +115,25 @@ def include_dismissed?
end
 
def dismissal_feedback?(finding)
if ::Feature.enabled?(:vulnerability_finding_fingerprints) && !finding.fingerprints.empty?
dismissal_feedback_by_finding_fingerprints(finding)
else
dismissal_feedback_by_project_fingerprint(finding)
end
end
def dismissal_feedback_by_finding_fingerprints(finding)
all_dismissals = strong_memoize(:all_dismissal_feedbacks) do
pipeline.project
.vulnerability_feedback
.for_dismissal
end
potential_uuids = Set.new([*finding.fingerprint_uuids, finding.uuid].compact)
all_dismissals.any? { |dismissal| potential_uuids.include?(dismissal.finding_uuid) }
end
def dismissal_feedback_by_project_fingerprint(finding)
dismissal_feedback_by_fingerprint[finding.project_fingerprint]
end
 
Loading
Loading
Loading
Loading
@@ -116,6 +116,9 @@ def security_report
# This will remove the duplicated findings within the artifact itself
::Security::MergeReportsService.new(report).execute
end
rescue StandardError => e
puts "Error fetching job artifact security report: #{e}"
puts e.backtrace.map {|x| " #{x}"}.join("\n")
end
 
# This method is necessary to remove the reference to the
Loading
Loading
Loading
Loading
@@ -341,12 +341,17 @@ def assets
end
end
 
alias_method :==, :eql? # eql? is necessary in some cases like array intersection
alias_method :==, :eql?
 
def eql?(other)
other.report_type == report_type &&
other.location_fingerprint == location_fingerprint &&
other.first_fingerprint == first_fingerprint
return false unless other.report_type == report_type && other.first_fingerprint == first_fingerprint
if ::Feature.enabled?(:vulnerability_finding_fingerprints)
# TODO add the uuid + 'hash' fingerprint type
matches_fingerprints(other.fingerprints, other.uuid)
else
other.location_fingerprint == location_fingerprint
end
end
 
# Array.difference (-) method uses hash and eql? methods to do comparison
Loading
Loading
@@ -378,6 +383,41 @@ def pipeline_branch
pipelines&.last&.sha || project.default_branch
end
 
# this should match the same code as in ee/lib/gitlab/ci/reports/security/finding.rb
def matches_fingerprints(other_fingerprints, other_uuid)
other_fingerprint_types = other_fingerprints.index_by(&:algorithm_type)
# highest first
match_result = nil
fingerprints.sort_by(&:priority).reverse_each do |fingerprint|
matching_other_fingerprint = other_fingerprint_types[fingerprint.algorithm_type]
next if matching_other_fingerprint.nil?
match_result = matching_other_fingerprint == fingerprint
break
end
if match_result.nil?
Set.new([uuid, *fingerprint_uuids]).include?(other_uuid)
else
match_result
end
end
def fingerprint_uuids
fingerprints.map do |fingerprint|
hex_sha = fingerprint.fingerprint_hex
Gitlab::UUID.v5(uuid_v5_name(location_fingerprint_value: hex_sha))
end
end
def fingerprint_uuids_and_priorities
fingerprints.map do |fingerprint|
hex_sha = fingerprint.fingerprint_sha256.unpack1("H*")
[Gitlab::UUID.v5(uuid_v5_name(location_fingerprint_value: hex_sha)), fingerprint.priority]
end
end
protected
 
def first_fingerprint
Loading
Loading
@@ -394,11 +434,11 @@ def finding_key
}
end
 
def uuid_v5_name
def uuid_v5_name(location_fingerprint_value: nil)
[
report_type,
primary_identifier.fingerprint,
location_fingerprint,
(primary_identifier || identifiers.first).fingerprint,
location_fingerprint_value || location_fingerprint,
project_id
].join('-')
end
Loading
Loading
Loading
Loading
@@ -9,5 +9,32 @@ class FindingFingerprint < ApplicationRecord
enum algorithm_type: { hash: 1, location: 2, scope_offset: 3 }, _prefix: :algorithm
 
validates :finding, presence: true
def self.priority(algorithm_type)
priorities = {
'scope_offset' => 3,
'location' => 2,
'hash' => 1
}
raise ArgumentError.new("No priority for #{algorithm_type.inspect}") unless priorities.key?(algorithm_type)
priorities[algorithm_type]
end
def fingerprint_hex
fingerprint_sha256.unpack1("H*")
end
def priority
self.class.priority(algorithm_type)
end
def eql?(other)
other.algorithm_type == algorithm_type &&
other.fingerprint_sha256 == fingerprint_sha256
end
alias_method :==, :eql?
end
end
Loading
Loading
@@ -49,14 +49,20 @@ def create_vulnerability_finding(finding)
return
end
 
vulnerability_params = finding.to_hash.except(:compare_key, :identifiers, :location, :scanner, :scan, :links)
vulnerability_params = finding.to_hash.except(:compare_key, :identifiers, :location, :scanner, :scan, :links, :fingerprints)
entity_params = Gitlab::Json.parse(vulnerability_params&.dig(:raw_metadata)).slice('description', 'message', 'solution', 'cve', 'location')
vulnerability_finding = create_or_find_vulnerability_finding(finding, vulnerability_params.merge(entity_params))
 
update_vulnerability_scanner(finding)
 
update_vulnerability_finding(vulnerability_finding, vulnerability_params)
reset_remediations_for(vulnerability_finding, finding)
if ::Feature.enabled?(:vulnerability_finding_fingerprints)
update_feedbacks(vulnerability_finding, vulnerability_params[:uuid])
end
update_finding_fingerprints(finding, vulnerability_finding)
 
# The maximum number of identifiers is not used in validation
Loading
Loading
@@ -72,8 +78,16 @@ def create_vulnerability_finding(finding)
create_vulnerability(vulnerability_finding, pipeline)
end
 
# rubocop: disable CodeReuse/ActiveRecord
def create_or_find_vulnerability_finding(finding, create_params)
if ::Feature.enabled?(:vulnerability_finding_fingerprints)
create_or_find_vulnerability_finding_with_fingerprints(finding, create_params)
else
create_or_find_vulnerability_finding_normal(finding, create_params)
end
end
# rubocop: disable CodeReuse/ActiveRecord
def create_or_find_vulnerability_finding_normal(finding, create_params)
find_params = {
scanner: scanners_objects[finding.scanner.key],
primary_identifier: identifiers_objects[finding.primary_identifier.key],
Loading
Loading
@@ -95,6 +109,48 @@ def create_or_find_vulnerability_finding(finding, create_params)
end
end
 
def create_or_find_vulnerability_finding_with_fingerprints(finding, create_params)
find_params = {
# this isn't taking prioritization into account (happens in the filter
# block below), but it *does* limit the number of findings we have to sift through
uuid: [finding.uuid, *finding.fingerprint_uuids],
scanner: scanners_objects[finding.scanner.key],
primary_identifier: identifiers_objects[finding.primary_identifier.key]
}
normalized_fingerprints = finding.fingerprints.map do |fingerprint|
::Vulnerabilities::FindingFingerprint.new(fingerprint.to_hash)
end
get_matched_findings = lambda {
project.vulnerability_findings.where(**find_params).filter do |vf|
vf.matches_fingerprints(normalized_fingerprints, finding.uuid)
end
}
matched_findings = get_matched_findings.call
begin
vulnerability_finding = matched_findings.first
if vulnerability_finding.nil?
find_params[:uuid] = finding.uuid
vulnerability_finding = project
.vulnerability_findings
.create_with(create_params)
.find_or_initialize_by(find_params)
end
vulnerability_finding.location_fingerprint = finding.location.fingerprint
vulnerability_finding.location = create_params.dig(:location)
vulnerability_finding.save!
vulnerability_finding
rescue ActiveRecord::RecordNotUnique
get_matched_findings.call.first
rescue ActiveRecord::RecordInvalid => e
Gitlab::ErrorTracking.track_and_raise_exception(e, create_params: create_params&.dig(:raw_metadata))
end
end
def update_vulnerability_scanner(finding)
scanner = scanners_objects[finding.scanner.key]
scanner.update!(finding.scanner.to_hash)
Loading
Loading
@@ -154,6 +210,13 @@ def create_vulnerability_pipeline_object(vulnerability_finding, pipeline)
end
# rubocop: enable CodeReuse/ActiveRecord
 
def update_feedbacks(vulnerability_finding, new_uuid)
vulnerability_finding.load_feedback.each do |feedback|
feedback.finding_uuid = new_uuid
feedback.save!
end
end
def update_finding_fingerprints(finding, vulnerability_finding)
to_delete = []
to_update = {}
Loading
Loading
@@ -173,14 +236,14 @@ def update_finding_fingerprints(finding, vulnerability_finding)
end
 
poro_fingerprints.delete(fingerprint.algorithm_type)
to_update[fingerprint.id] = poro_fingerprint.to_h
to_update[fingerprint.id] = poro_fingerprint.to_hash
end
 
# any remaining poro fingerprints left are new
poro_fingerprints.values.each do |poro_fingerprint|
to_create << {
finding_id: vulnerability_finding.id,
**poro_fingerprint.to_h
**poro_fingerprint.to_hash
}
end
 
Loading
Loading
---
title: Use finding fingerprints
merge_request: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54608
author:
type: added
---
name: vulnerability_finding_fingerprints
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54608
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/322044
milestone: '13.9'
type: development
group: group::vulnerability research
default_enabled: false
Loading
Loading
@@ -6,6 +6,42 @@ module BackgroundMigration
module UpdateLocationFingerprintForContainerScanningFindings
extend ::Gitlab::Utils::Override
 
module UUID
NAMESPACE_IDS = {
development: "a143e9e2-41b3-47bc-9a19-081d089229f4",
test: "a143e9e2-41b3-47bc-9a19-081d089229f4",
staging: "a6930898-a1b2-4365-ab18-12aa474d9b26",
production: "58dc0f06-936c-43b3-93bb-71693f1b6570"
}.freeze
UUID_V5_PATTERN = /\h{8}-\h{4}-5\h{3}-\h{4}-\h{4}\h{8}/.freeze
NAMESPACE_REGEX = /(\h{8})-(\h{4})-(\h{4})-(\h{4})-(\h{4})(\h{8})/.freeze
PACK_PATTERN = "NnnnnN".freeze
class << self
def v5(name, namespace_id: default_namespace_id)
Digest::UUID.uuid_v5(namespace_id, name)
end
private
def default_namespace_id
@default_namespace_id ||= begin
namespace_uuid = NAMESPACE_IDS.fetch(Rails.env.to_sym)
# Digest::UUID is broken when using a UUID as a namespace_id
# https://github.com/rails/rails/issues/37681#issue-520718028
namespace_uuid.scan(NAMESPACE_REGEX).flatten.map { |s| s.to_i(16) }.pack(PACK_PATTERN)
end
end
end
end
class Identifier < ActiveRecord::Base
include ::EachBatch
self.table_name = 'vulnerability_identifiers'
end
class Finding < ActiveRecord::Base
include ::ShaAttribute
include ::EachBatch
Loading
Loading
@@ -27,6 +63,20 @@ def calculate_new_fingerprint(image, package_name)
Digest::SHA1.hexdigest("#{docker_image_name_without_tag(image)}:#{package_name}")
end
 
def calculate_new_uuid(fingerprint)
primary_identifier = Identifier.select(:fingerprint).where(id: primary_identifier_id).first
return if primary_identifier.nil?
parts = [
report_type,
primary_identifier.fingerprint,
fingerprint,
project_id
]
UUID.v5(parts.join('-'))
end
private
 
def docker_image_name_without_tag(image)
Loading
Loading
@@ -51,19 +101,22 @@ def version_semver_like?(version)
override :perform
def perform(start_id, stop_id)
Finding.container_scanning
.select(:id, "raw_metadata::json->'location' AS loc")
.select(:id, "raw_metadata::json->'location' AS loc", :report_type, :project_id, :primary_identifier_id)
.where(id: start_id..stop_id)
.each do |finding|
next if finding.loc.nil?
 
package = finding.loc.dig('dependency', 'package', 'name')
image = finding.loc.dig('image')
new_fingerprint = finding.calculate_new_fingerprint(image, package)
 
new_fingerprint = finding.calculate_new_fingerprint(image, package)
next if new_fingerprint.blank?
 
new_uuid = finding.calculate_new_uuid(new_fingerprint)
next if new_uuid.blank?
begin
finding.update_column(:location_fingerprint, new_fingerprint)
finding.update_columns(location_fingerprint: new_fingerprint, uuid: new_uuid)
rescue ActiveRecord::RecordNotUnique
::Gitlab::BackgroundMigration::Logger.warn("Duplicate finding found with finding id #{finding.id}")
end
Loading
Loading
Loading
Loading
@@ -80,11 +80,20 @@ def create_vulnerability(data)
links = create_links(data['links'])
location = create_location(data['location'] || {})
remediations = create_remediations(data['remediations'])
fingerprints = create_fingerprints(tracking_data(data))
fingerprints = create_fingerprints(location, tracking_data(data))
if ::Feature.enabled?(:vulnerability_finding_fingerprints) && !fingerprints.empty?
# NOT the fingerprint_sha256 - the compare key is hashed
# to create the project_fingerprint
highest_priority_fingerprint = fingerprints.max_by(&:priority)
uuid = calculate_uuid_v5(identifiers.first, highest_priority_fingerprint.fingerprint_hex)
else
uuid = calculate_uuid_v5(identifiers.first, location&.fingerprint)
end
 
report.add_finding(
::Gitlab::Ci::Reports::Security::Finding.new(
uuid: calculate_uuid_v5(identifiers.first, location),
uuid: uuid,
report_type: report.type,
name: finding_name(data, identifiers, location),
compare_key: data['cve'] || '',
Loading
Loading
@@ -99,13 +108,15 @@ def create_vulnerability(data)
raw_metadata: data.to_json,
metadata_version: report_version,
details: data['details'] || {},
fingerprints: fingerprints))
fingerprints: fingerprints,
project_id: report.project_id))
end
 
def create_fingerprints(tracking)
return [] if tracking.nil?
def create_fingerprints(location, tracking)
tracking ||= { 'items' => [] }
 
fingerprint_algorithms = {}
tracking['items'].each do |item|
next unless item.key?('fingerprints')
 
Loading
Loading
@@ -116,17 +127,21 @@ def create_fingerprints(tracking)
end
end
 
if fingerprint_algorithms.empty?
is_location = [:file_path, :start_line].all? { |x| location.respond_to?(x) }
type = is_location ? 'location' : 'hash'
fingerprint_algorithms[type] = [location.fingerprint_data]
end
fingerprint_algorithms.map do |algorithm, values|
value = values.join('|')
begin
::Gitlab::Ci::Reports::Security::FindingFingerprint.new(
algorithm_type: algorithm,
fingerprint_value: value
)
rescue ArgumentError
# TODO log the invalid algorithm type
nil
end
fingerprint = ::Gitlab::Ci::Reports::Security::FindingFingerprint.new(
algorithm_type: algorithm,
fingerprint_value: value
)
next unless fingerprint.valid?
fingerprint
end.compact
end
 
Loading
Loading
@@ -193,6 +208,10 @@ def create_location(location_data)
raise NotImplementedError
end
 
def create_tracking_location(tracking_data, fingerprint)
Reports::Security::Locations::Tracking.new(tracking_data, fingerprint)
end
def finding_name(data, identifiers, location)
return data['message'] if data['message'].present?
return data['name'] if data['name'].present?
Loading
Loading
@@ -201,11 +220,11 @@ def finding_name(data, identifiers, location)
"#{identifier.name} in #{location&.fingerprint_path}"
end
 
def calculate_uuid_v5(primary_identifier, location)
def calculate_uuid_v5(primary_identifier, location_fingerprint)
uuid_v5_name_components = {
report_type: report.type,
primary_identifier_fingerprint: primary_identifier&.fingerprint,
location_fingerprint: location&.fingerprint,
location_fingerprint: location_fingerprint,
project_id: report.project_id
}
 
Loading
Loading
Loading
Loading
@@ -25,10 +25,11 @@ class Finding
attr_reader :remediations
attr_reader :details
attr_reader :fingerprints
attr_reader :project_id
 
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, details: {}, fingerprints: []) # 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: {}, fingerprints: [], project_id: nil) # rubocop:disable Metrics/ParameterLists
@compare_key = compare_key
@confidence = confidence
@identifiers = identifiers
Loading
Loading
@@ -45,6 +46,7 @@ def initialize(compare_key:, identifiers:, links: [], remediations: [], location
@remediations = remediations
@details = details
@fingerprints = fingerprints
@project_id = project_id
 
@project_fingerprint = generate_project_fingerprint
end
Loading
Loading
@@ -66,6 +68,7 @@ def to_hash
severity
uuid
details
fingerprints
].each_with_object({}) do |key, hash|
hash[key] = public_send(key) # rubocop:disable GitlabSecurity/PublicSend
end
Loading
Loading
@@ -85,13 +88,22 @@ def unsafe?
end
 
def eql?(other)
report_type == other.report_type &&
location.fingerprint == other.location.fingerprint &&
primary_fingerprint == other.primary_fingerprint
return false unless report_type == other.report_type && primary_fingerprint == other.primary_fingerprint
if ::Feature.enabled?(:vulnerability_finding_fingerprints)
matches_fingerprints(other.fingerprints, other.uuid)
else
location.fingerprint == other.location.fingerprint
end
end
 
def hash
report_type.hash ^ location.fingerprint.hash ^ primary_fingerprint.hash
if Feature.enabled?(:vulnerability_finding_fingerprints) && !fingerints.empty?
highest_fingerprint = fingerprints.max_by(&:priority)
report_type.hash ^ highest_fingerprint.fingerprint_hex.hash ^ primary_fingerprint.hash
else
report_type.hash ^ location.fingerprint.hash ^ primary_fingerprint.hash
end
end
 
def valid?
Loading
Loading
@@ -108,11 +120,48 @@ def primary_fingerprint
primary_identifier&.fingerprint
end
 
# this should match the same code as in ee/app/models/vulnerabilities/finding.rb
def matches_fingerprints(other_fingerprints, other_uuid)
other_fingerprint_types = other_fingerprints.index_by(&:algorithm_type)
# highest first
match_result = nil
fingerprints.sort_by(&:priority).reverse_each do |fingerprint|
matching_other_fingerprint = other_fingerprint_types[fingerprint.algorithm_type]
next if matching_other_fingerprint.nil?
match_result = matching_other_fingerprint == fingerprint
break
end
if match_result.nil?
Set.new([uuid, *fingerprint_uuids]).include?(other_uuid)
else
match_result
end
end
def fingerprint_uuids
fingerprints.map do |fingerprint|
hex_sha = fingerprint.fingerprint_hex
Gitlab::UUID.v5(uuid_v5_name(location_fingerprint_value: hex_sha))
end
end
private
 
def generate_project_fingerprint
Digest::SHA1.hexdigest(compare_key)
end
def uuid_v5_name(location_fingerprint_value: nil)
[
report_type,
primary_identifier.fingerprint,
location_fingerprint_value || location.fingerprint,
project_id
].join('-')
end
end
end
end
Loading
Loading
Loading
Loading
@@ -10,22 +10,37 @@ class FindingFingerprint
def initialize(params = {})
@algorithm_type = params.dig(:algorithm_type)
@fingerprint_value = params.dig(:fingerprint_value)
end
def valid?
::Vulnerabilities::FindingFingerprint.algorithm_types.key?(algorithm_type)
end
 
unless ::Vulnerabilities::FindingFingerprint.algorithm_types.key?(algorithm_type)
raise ArgumentError.new("Unsupported algorithm type: #{algorithm_type.inspect}")
end
def priority
::Vulnerabilities::FindingFingerprint.priority(algorithm_type)
end
 
def fingerprint_sha256
Digest::SHA256.digest(fingerprint_value)
Digest::SHA1.digest(fingerprint_value)
end
def fingerprint_hex
fingerprint_sha256.unpack1("H*")
end
 
def to_h
def to_hash
{
algorithm_type: algorithm_type,
fingerprint_sha256: fingerprint_sha256
}
end
def eql?(other)
other.algorithm_type == algorithm_type &&
other.fingerprint_sha256 == fingerprint_sha256
end
alias_method :==, :eql?
end
end
end
Loading
Loading
Loading
Loading
@@ -18,12 +18,12 @@ def initialize(image:, operating_system:, package_name: nil, package_version: ni
@package_version = package_version
end
 
private
def fingerprint_data
"#{docker_image_name_without_tag}:#{package_name}"
end
 
private
def docker_image_name_without_tag
base_name, version = image.split(':')
 
Loading
Loading
Loading
Loading
@@ -16,8 +16,6 @@ def initialize(crash_address:, crash_type:, crash_state:)
@crash_state = crash_state
end
 
private
def fingerprint_data
"#{crash_type}:#{crash_state}"
end
Loading
Loading
Loading
Loading
@@ -20,8 +20,6 @@ def initialize(hostname:, method_name:, path:, param: nil)
 
alias_method :fingerprint_path, :path
 
private
def fingerprint_data
"#{path}:#{method_name}:#{param}"
end
Loading
Loading
Loading
Loading
@@ -18,8 +18,6 @@ def initialize(file_path:, package_name:, package_version: nil)
@package_version = package_version
end
 
private
def fingerprint_data
"#{file_path}:#{package_name}"
end
Loading
Loading
Loading
Loading
@@ -22,8 +22,6 @@ def initialize(file_path:, start_line:, end_line: nil, class_name: nil, method_n
@start_line = start_line
end
 
private
def fingerprint_data
"#{file_path}:#{start_line}:#{end_line}"
end
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment