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).



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/opentrace/pii_scrubber.rb', line 25

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



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

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