Class: Contrast::Agent::Assess::Rule::Provider::HardcodedPassword

Inherits:
Object
  • Object
show all
Includes:
HardcodedValueRule
Defined in:
lib/contrast/agent/assess/rule/provider/hardcoded_password.rb

Overview

Determine if there are any passwords hardcoded into the sourcecode of the application. A constant is a password if: 1) the name contains a PASSWORD_FIELD_NAMES value 2) the name does not contain a NON_PASSWORD_PARTIAL_NAMES value 3) the value is a String 4) the value is not solely alphanumeric and ‘.’ or ‘_’ * note that

mixing the characters counts as a violation of this rule

Constant Summary collapse

NAME =
'hardcoded-password'
PASSWORD_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[PASSWORD PASSKEY PASSPHRASE SECRET].cs__freeze
NON_PASSWORD_PARTIAL_NAMES =

These are markers whose presence indicates that a field is more likely to be a descriptor or requirement than an actual password. We should ignore fields that contain them.

%w[DATE FORGOT FORM ENCODE PATTERN PREFIX PROP SUFFIX URL BASE FILE URI].cs__freeze
PROPERTY_NAME_PATTERN =

If a field name matches an expected password field, we’ll check it’s value to see if it looks like a placeholder. For our purposes, placeholders will be any non-empty String conforming to the patterns below. We do combine the patterns with [._] as in Ruby these two characters are probably more likely to appear together in a default placeholder than in a password. Note this is opposite of the behavior in Java

/^[a-z]+[._][._a-z]*[a-z]+$/.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

Methods included from HardcodedValueRule

#analyze, #constant_name?, #disabled?, #parse

Methods included from Components::Interface

included

Instance Method Details

#name_passes?(constant_string) ⇒ Boolean

If the constant looks like a password and it doesn’t look like a password descriptor, it passes for this rule

Returns:

  • (Boolean)


36
37
38
39
# File 'lib/contrast/agent/assess/rule/provider/hardcoded_password.rb', line 36

def name_passes? constant_string
  PASSWORD_FIELD_NAMES.any? { |name| constant_string.index(name) } &&
      NON_PASSWORD_PARTIAL_NAMES.none? { |name| constant_string.index(name) }
end

#probably_property_name?(value) ⇒ Boolean

Returns:

  • (Boolean)


63
64
65
# File 'lib/contrast/agent/assess/rule/provider/hardcoded_password.rb', line 63

def probably_property_name? value
  value.match?(PROPERTY_NAME_PATTERN)
end

#redacted_markerObject



68
69
70
# File 'lib/contrast/agent/assess/rule/provider/hardcoded_password.rb', line 68

def redacted_marker
  REDACTED_MARKER
end

#rule_idObject



20
21
22
# File 'lib/contrast/agent/assess/rule/provider/hardcoded_password.rb', line 20

def rule_id
  NAME
end

#value_node_passes?(value_node) ⇒ Boolean

Determine if the given value node violates the hardcode key rule

Parameters:

  • value_node (RubyVM::AbstractSyntaxTree::Node)

    the node to evaluate

Returns:

  • (Boolean)


45
46
47
48
49
50
51
52
53
# File 'lib/contrast/agent/assess/rule/provider/hardcoded_password.rb', line 45

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)
  return false unless value_node.type == :STR

  # https://www.rubydoc.info/gems/ruby-internal/Node/STR
  string = value_node.children[0]
  !probably_property_name?(string)
end

#value_passes?(value) ⇒ Boolean

If the value probably isn’t a property name, it passes for this rule

Returns:

  • (Boolean)


80
81
82
# File 'lib/contrast/agent/assess/rule/provider/hardcoded_password.rb', line 80

def value_passes? value
  !probably_property_name?(value)
end

#value_type_passes?(value) ⇒ Boolean

TODO: RUBY-1014 remove ‘#value_type_passes?` and `#value_passes?` If the value is a string, it passes for this rule

Returns:

  • (Boolean)


74
75
76
# File 'lib/contrast/agent/assess/rule/provider/hardcoded_password.rb', line 74

def value_type_passes? value
  value.is_a?(String)
end