Module: OpenTrace::PiiScrubber

Defined in:
lib/opentrace/pii_scrubber.rb

Constant Summary collapse

REDACTED =
"[REDACTED]"
PATTERNS =
{
  credit_card: /\b(?:\d[ -]*?){13,16}\b/,
  email: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/,
  ssn: /\b\d{3}-\d{2}-\d{4}\b/,
  phone: /\b(?:\+?1[-.\s]?)?\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}\b/,
  bearer_token: /Bearer\s+[A-Za-z0-9\-._~+\/]+=*/,
  api_key: /\b(?:sk|pk|api[_-]?key)[_-][A-Za-z0-9]{20,}\b/i
}.freeze
SENSITIVE_KEYS =
Set.new(%w[
  password passwd secret token api_key apikey
  authorization auth_token access_token refresh_token
  credit_card card_number cvv ssn
]).freeze

Class Method Summary collapse

Class Method Details

.scrub!(hash, patterns: nil) ⇒ Object

Scrub PII from a payload hash (in-place mutation for performance).



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
53
54
# File 'lib/opentrace/pii_scrubber.rb', line 27

def scrub!(hash, patterns: nil)
  return hash unless hash.is_a?(Hash)

  active_patterns = patterns || PATTERNS.values

  hash.each do |key, value|
    key_s = key.to_s.downcase
    if SENSITIVE_KEYS.include?(key_s)
      hash[key] = REDACTED
    elsif value.is_a?(String)
      hash[key] = scrub_string(value, active_patterns)
    elsif value.is_a?(Hash)
      scrub!(value, patterns: active_patterns)
    elsif value.is_a?(Array)
      value.each_with_index do |v, i|
        if v.is_a?(String)
          value[i] = scrub_string(v, active_patterns)
        elsif v.is_a?(Hash)
          scrub!(v, patterns: active_patterns)
        end
      end
    end
  end

  hash
rescue StandardError
  hash
end

.scrub_string(str, patterns) ⇒ Object



56
57
58
59
60
61
62
63
64
# File 'lib/opentrace/pii_scrubber.rb', line 56

def scrub_string(str, patterns)
  result = str
  patterns.each do |pattern|
    result = result.gsub(pattern, REDACTED)
  end
  result
rescue StandardError
  str
end