Module: Contrast::Agent::Assess::Rule::Provider::HardcodedValueRule
- Includes:
- Components::Interface
- Included in:
- HardcodedKey, HardcodedPassword
- Defined in:
- lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb
Overview
Hardcoded rules detect if any secret value has been written directly into the sourcecode of the application. To use this base class, a provider must implement three methods: 1) name_passes? : does the constant name match a given value set 2) value_node_passes? : does the value of the constant match a
given value set
3) redacted_marker : the value to plug in for the obfuscated value
Constant Summary collapse
- COMMON_CONSTANTS =
TODO: RUBY-1014 - remove ‘#analyze`
%i[ CONTRAST_ASSESS_POLICY_STATUS VERSION ].cs__freeze
- CONSTANT_NAME_PATTERN =
Constants can be variable or classes defined in the given class. We ONLY want the variables, which should be defined in the MACRO_CASE (upper case & underscore format)
/^[A-Z_]+$/.cs__freeze
- CONSTANT_NAME_KEY =
The name of the field
'name'- CODE_SOURCE_KEY =
The code line, recreated, with the password obfuscated
'codeSource'- SOURCE_KEY =
The constant name
'source'
Instance Method Summary collapse
- #analyze(clazz) ⇒ Object
- #constant_name?(constant) ⇒ Boolean
- #disabled? ⇒ Boolean
-
#parse(trace_point, ast) ⇒ Object
Parse the file pertaining to the given TracePoint to walk its AST to determine if a Constant is hardcoded.
Methods included from Components::Interface
Instance Method Details
#analyze(clazz) ⇒ Object
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb', line 33 def analyze clazz return if disabled? # we only want the constants explicitly defined in this class, not # those of its ancestor(s) constants = clazz.cs__constants(false) # if there are no constants, let's just leave return unless constants&.any? constants.each do |constant| next if COMMON_CONSTANTS.include?(constant) # if this class autoloads its constant, get the hell away from it # I mean it! Don't even think about it. # # Autoload means this constant (usually [always?] a class or # module) won't be required until something in the application # tries to load it. We CANNOT be that thing. We'll just have to # wait until it's loaded, at which point we'll be handed it # again. next if clazz.cs__autoload?(constant) # constant comes to us as a symbol. that sucks. we need to do # some string methods on it, so stringify it. constant_string = constant.to_s # if this is another class or a module, move on next unless constant_name?(constant_string) next unless name_passes?(constant_string) value = clazz.cs__const_get(constant, false) # if the constant isn't holding a string, skip it next unless value_type_passes?(value) # if it looks like a placeholder / pointer to a config, skip it next unless value_passes?(value) build_finding(clazz, constant_string) end end |
#constant_name?(constant) ⇒ Boolean
102 103 104 |
# File 'lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb', line 102 def constant_name? constant constant.match?(CONSTANT_NAME_PATTERN) end |
#disabled? ⇒ Boolean
24 25 26 |
# File 'lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb', line 24 def disabled? !ASSESS.enabled? || ASSESS.rule_disabled?(rule_id) end |
#parse(trace_point, ast) ⇒ Object
Parse the file pertaining to the given TracePoint to walk its AST to determine if a Constant is hardcoded. For our purposes, this hard coding means directly set rather than as an interpolated String or through a method call.
Note: This is a top layer check, we make no assertions about what the methods or interpolations do. Their presence, even if only calling a hardcoded thing, causes this check to not report.
90 91 92 93 94 95 96 |
# File 'lib/contrast/agent/assess/rule/provider/hardcoded_value_rule.rb', line 90 def parse trace_point, ast return if disabled? parse_ast(trace_point.self, ast) rescue StandardError => e logger.error('Unable to parse AST for hardcoded keys', e, module: trace_point.self) end |