Class: Scryer::Rules::HardcodedSecretKeyBaseRule
- Inherits:
-
Scryer::Rule
- Object
- Scryer::Rule
- Scryer::Rules::HardcodedSecretKeyBaseRule
- Defined in:
- lib/scryer/rules/hardcoded_secret_key_base_rule.rb
Overview
Flags config.secret_key_base = "literal" (or
Rails.application.config.secret_key_base = "literal") — a plain
string literal assigned to secret_key_base via a .field= target.
HardcodedSecretRule doesn't catch this shape: its target_name walks
the assignment target depth-first and returns the first identifier
it finds, which for a .field= target with a receiver is the
receiver's own name (config) rather than the attribute being
assigned (secret_key_base) — so config.secret_key_base = "..."
never matches its NAME_PATTERN, even though the value is exactly the
kind of credential that rule exists to catch. Bare assignment
(secret_key_base = "..." with no receiver) IS already caught by
HardcodedSecretRule, since there the identifier IS the target name —
this rule only covers the receiver'd shape it misses.
Constant Summary collapse
- PLACEHOLDER_VALUES =
/\A(x+|0+|change-?me|placeholder|example|dummy|fake|test|redacted|\*+)\z/i.freeze
Instance Attribute Summary
Attributes inherited from Scryer::Rule
Instance Method Summary collapse
Methods inherited from Scryer::Rule
Constructor Details
This class inherits a constructor from Scryer::Rule
Instance Method Details
#scan ⇒ Object
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/scryer/rules/hardcoded_secret_key_base_rule.rb', line 25 def scan findings = [] Ast.each_node(sexp) do |node| next unless Ast.tagged?(node, :assign) target = node[1] next unless Ast.tagged?(target, :field) next unless Ast.ident_text(target[3]) == "secret_key_base" value = Ast.plain_string_value(node[2]) next unless value && !value.strip.empty? && !PLACEHOLDER_VALUES.match?(value.strip) line = Ast.line_of(node) findings << finding( line: line, message: "`secret_key_base` is assigned a literal string — this key signs/encrypts " \ "Rails sessions and other secrets; anyone with read access to this source " \ "(including git history) can forge session cookies and other signed data.", suggested_fix: "Use `Rails.application.credentials.secret_key_base` (the Rails default, " \ "set via `bin/rails credentials:edit`) or `ENV.fetch(\"SECRET_KEY_BASE\")` " \ "instead, and rotate this key since it's likely already exposed in git " \ "history." ) end findings end |