lib/contrast/utils/hash_digest.rb in contrast-agent-4.13.1 vs lib/contrast/utils/hash_digest.rb in contrast-agent-4.14.0

- old
+ new

@@ -1,9 +1,10 @@ # Copyright (c) 2021 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true require 'digest' +require 'contrast/utils/hash_digest_extend' module Contrast module Utils # We use this class to provide hashes for our Request and Finding objects # based upon our definitions of uniqueness. @@ -11,89 +12,20 @@ # Ruby agent, the uniqueness of the Finding hash is defined by a # specification shared across all agent teams. The spec can be found here: # https://bitbucket.org/contrastsecurity/assess-specifications/src/master/vulnerability/preflight.md class HashDigest < Digest::Class include Digest::Instance + extend Contrast::Utils::HashDigestExtend CONTENT_LENGTH_HEADER = 'Content-Length' CRYPTO_RULES = %w[crypto-bad-ciphers crypto-bad-mac].cs__freeze CONFIG_PATH_KEY = 'path' CONFIG_SESSION_ID_KEY = 'sessionId' CLASS_SOURCE_KEY = 'source' CLASS_CONSTANT_NAME_KEY = 'name' CLASS_LINE_NO_KEY = 'lineNo' - class << self - def generate_request_hash request - hash = new - hash.update(request.request_method) - hash.update(request.normalized_uri) - request.parameters.each_key do |name| - hash.update(name) - end - cl = request.headers[CONTENT_LENGTH_HEADER] - hash.update_on_content_length(cl) if cl - hash.finish - end - def generate_event_hash finding, source, request - return generate_dataflow_hash(finding, request) if finding.events.length.to_i > 1 - - id = finding.rule_id - return generate_crypto_hash(finding, source, request) if CRYPTO_RULES.include?(id) - - generate_trigger_hash(finding, request) - end - - def generate_config_hash finding - hash = new - hash.update(finding.rule_id) - path = finding.properties[CONFIG_PATH_KEY] - hash.update(path) - method = finding.properties[CONFIG_SESSION_ID_KEY] - hash.update(method) - hash.finish - end - - def generate_class_scanning_hash finding - hash = new - hash.update(finding.rule_id) - module_name = finding.properties[CLASS_SOURCE_KEY] - hash.update(module_name) - # We're not currently collecting this. 30/7/19 HM - line_no = finding.properties[CLASS_LINE_NO_KEY] - hash.update(line_no) - field = finding.properties[CLASS_CONSTANT_NAME_KEY] - hash.update(field) - hash.finish - end - - private - - def generate_crypto_hash finding, algorithm, request - hash = new - hash.update(finding.rule_id) - hash.update(algorithm) - hash.update_on_request(finding, request) - hash.finish - end - - def generate_dataflow_hash finding, request - hash = new - hash.update(finding.rule_id) - hash.update_on_sources(finding.events) - hash.update_on_request(finding, request) - hash.finish - end - - def generate_trigger_hash finding, request - hash = new - hash.update(finding.rule_id) - hash.update_on_request(finding, request) - hash.finish - end - end - def update_on_request finding, request if (route = finding.routes[0]) update(route.route) update(route.verb) elsif request ||= Contrast::Agent::REQUEST_TRACKER.current&.request @@ -104,12 +36,17 @@ def update_on_sources events return unless events&.any? events.each do |event| - event.event_sources.each do |source| - update(source.type) - update(source.name) # rubocop:disable Security/Module/Name -- API attribute. + if event.cs__is_a?(Contrast::Api::Dtm::TraceEvent) + event.event_sources&.each do |source| + update(source.type) + update(source.name) # rubocop:disable Security/Module/Name + end + elsif event.cs__is_a?(Contrast::Agent::Assess::Events::SourceEvent) + update(event.source_type) + update(event.source_name) end end end CHARS = %w[a b c d e f g].cs__freeze