Class: Contrast::Agent::Assess::Rule::Provider::HardcodedKey
- Includes:
- HardcodedValueRule
- Defined in:
- lib/contrast/agent/assess/rule/provider/hardcoded_key.rb
Overview
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
Constant Summary collapse
- NAME =
'hardcoded-key'- KEY_FIELD_NAMES =
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.
%w[KEY AES DES IV SECRET].cs__freeze
- NON_KEY_PARTIAL_NAMES =
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.
%w[CONTENT_CODES RESPONSE_CODES ERROR_CODES].cs__freeze
- BYTE_HOLDERS =
%i[ARRAY LIST].cs__freeze
- REDACTED_MARKER =
' = [**REDACTED**]'
Constants included from HardcodedValueRule
Contrast::Agent::Assess::Rule::Provider::HardcodedValueRule::CODE_SOURCE_KEY, Contrast::Agent::Assess::Rule::Provider::HardcodedValueRule::COMMON_CONSTANTS, Contrast::Agent::Assess::Rule::Provider::HardcodedValueRule::CONSTANT_NAME_KEY, Contrast::Agent::Assess::Rule::Provider::HardcodedValueRule::CONSTANT_NAME_PATTERN, Contrast::Agent::Assess::Rule::Provider::HardcodedValueRule::SOURCE_KEY
Instance Method Summary collapse
-
#bytes_call?(value_node) ⇒ Boolean
A node is a bytes_call if it’s the Node for String#bytes.
- #name_passes?(constant_string) ⇒ Boolean
- #redacted_marker ⇒ Object
- #rule_id ⇒ Object
-
#value_node_passes?(value_node) ⇒ Boolean
Determine if the given value node violates the hardcode key rule.
-
#value_passes?(_value) ⇒ Boolean
There isn’t a filter for the byte value.
-
#value_type_passes?(value) ⇒ Boolean
TODO: RUBY-1014 remove ‘#value_type_passes?` and `#value_passes?` If the value is a byte array, or at least an array of numbers, it passes for this rule.
Methods included from HardcodedValueRule
#analyze, #constant_name?, #disabled?, #parse
Methods included from Components::Interface
Instance Method Details
#bytes_call?(value_node) ⇒ Boolean
A node is a bytes_call if it’s the Node for String#bytes. We care about this specifically as it’s likely to be a common way to generate a key constant, rather than directly declaring an integer array.
79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/contrast/agent/assess/rule/provider/hardcoded_key.rb', line 79 def bytes_call? value_node return false unless value_node.type == :CALL children = value_node.children return false unless children return false unless children.length >= 2 potential_string_node = children[0] return false unless potential_string_node.cs__is_a?(RubyVM::AbstractSyntaxTree::Node) && potential_string_node.type == :STR children[1] == :bytes end |
#name_passes?(constant_string) ⇒ Boolean
31 32 33 34 |
# File 'lib/contrast/agent/assess/rule/provider/hardcoded_key.rb', line 31 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 |
#redacted_marker ⇒ Object
67 68 69 |
# File 'lib/contrast/agent/assess/rule/provider/hardcoded_key.rb', line 67 def redacted_marker REDACTED_MARKER end |
#rule_id ⇒ Object
17 18 19 |
# File 'lib/contrast/agent/assess/rule/provider/hardcoded_key.rb', line 17 def rule_id NAME end |
#value_node_passes?(value_node) ⇒ Boolean
Determine if the given value node violates the hardcode key rule
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/contrast/agent/assess/rule/provider/hardcoded_key.rb', line 41 def value_node_passes? value_node # If it's a freeze call, then evaluate the entity being frozen value_node = value_node.children[0] if freeze_call?(value_node) # If it's a String being turned into bytes, then it matches key # expectations return true if bytes_call?(value_node) type = value_node.type return false unless BYTE_HOLDERS.include?(type) return false unless value_node.children.any? # Unless this is an array of literal numerics, we don't match. # That array seems to always end in a nil value, so we allow # those as well. value_node.children.each do |child| next unless child return false unless child.cs__is_a?(RubyVM::AbstractSyntaxTree::Node) && child.type == :LIT && child.children[0]&.cs__is_a?(Integer) end true end |
#value_passes?(_value) ⇒ Boolean
There isn’t a filter for the byte value. The check is not evaluated for this rule
107 108 109 |
# File 'lib/contrast/agent/assess/rule/provider/hardcoded_key.rb', line 107 def value_passes? _value true end |
#value_type_passes?(value) ⇒ Boolean
TODO: RUBY-1014 remove ‘#value_type_passes?` and `#value_passes?` If the value is a byte array, or at least an array of numbers, it passes for this rule
96 97 98 99 100 101 102 103 |
# File 'lib/contrast/agent/assess/rule/provider/hardcoded_key.rb', line 96 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 |