# Copyright (c) 2020 Contrast Security, Inc. See https://www.contrastsecurity.com/enduser-terms-0317a for more details. # frozen_string_literal: true module Contrast module Agent module Assess module Rule module Provider # Determine if there are any cryptographic keys hardcoded into the sourcecode # of the application. A constant is a cryptographic key if: # 1) the name contains a KEY_FIELD_NAME value # 2) the value is a non-empty array of only Fixnums class HardcodedKey include Contrast::Agent::Assess::Rule::Provider::HardcodedValueRule NAME = 'hardcoded-key' def rule_id NAME end # These are names, determined by the security team (Matt & Ar), that # indicate a field is likely to be a password or secret token of some # sort. KEY_FIELD_NAMES = %w[KEY AES DES IV SECRET].cs__freeze # These are markers whose presence indicates that a field is more # likely to be a descriptor or requirement than an actual key. # We should ignore fields that contain them. NON_KEY_PARTIAL_NAMES = %w[CONTENT_CODES RESPONSE_CODES ERROR_CODES].cs__freeze def name_passes? constant_string KEY_FIELD_NAMES.any? { |name| constant_string.index(name) } && NON_KEY_PARTIAL_NAMES.none? { |name| constant_string.index(name) } end # If the value is a byte array, or at least an array of numbers, it # passes for this rule def value_type_passes? value return false unless value.is_a?(Array) && value.any? value.each do |byte| return false unless byte.is_a?(Integer) end true end # There isn't a filter for the byte value. The check is not evaluated # for this rule def value_passes? _value true end REDACTED_MARKER = ' = [**REDACTED**]' def redacted_marker REDACTED_MARKER end end end end end end end