Module: BetterNewrelicSqlObfuscator

Defined in:
lib/better_newrelic_sql_obfuscator.rb

Constant Summary collapse

WhitelistHash =

Provide a facility for whitelisting certain fields

Hash.new(false)
DontObfuscateProcs =
[]
ComparisonExpression =

Should match:

f_table_name = 'sensitive data'
"some_table"."some_field" = 'sensitive data'
"some_table"."some_field" somehow_matches 'sensitive data'

…but see also test/unit/lib/sql_obfuscator_unit_test.rb

/(?:("\w+"\."\w+")([^"']+)?)?'([^'\\]*((?:\\.|'')[^'\\]+)*)'/

Class Method Summary collapse

Class Method Details

.dont_obfuscate_table_and_field(&proc) ⇒ Object

Provides a facility for not obfuscating if the field meets some arbitrary criteria. Takes blocks, calls them on expressions for which a table and field can be found. Blocks should take two arguments, table and field, and return TRUE if the value should NOT be obfuscated.



37
38
39
# File 'lib/better_newrelic_sql_obfuscator.rb', line 37

def dont_obfuscate_table_and_field(&proc)
  DontObfuscateProcs << proc
end

.obfuscate(sql) ⇒ Object

Actually do the obfuscation



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/better_newrelic_sql_obfuscator.rb', line 49

def obfuscate(sql)
  sql.gsub(ComparisonExpression) do |match|
    field_expression, comparison, sensitive_data = $1, $2, $3

    # Obfuscate by default
    obfuscated_sql = [field_expression, comparison, obfuscate_value(sensitive_data)].compact.join

    # Don't obfuscate if we have a field expression that's on the whitelist or is on a 'nickname' field
    unless field_expression.to_s.empty?
      table_name, field_name = field_expression.to_s.gsub('"', '').split('.')
      case
      when whitelisted?('%s.%s' % [table_name, field_name])
        obfuscated_sql = match
      when DontObfuscateProcs.any? { |proc| proc.call(table_name, field_name) }
        obfuscated_sql = match
      end
    end

    obfuscated_sql
  end
end

.obfuscate_value(value) ⇒ Object



71
72
73
# File 'lib/better_newrelic_sql_obfuscator.rb', line 71

def obfuscate_value(value)
  "'%s'" % Digest::MD5.hexdigest("%d:%s" % [value.to_s.length, value.to_s])
end

.whitelist(field_expression) ⇒ Object



26
27
28
# File 'lib/better_newrelic_sql_obfuscator.rb', line 26

def whitelist(field_expression)
  WhitelistHash[field_expression] = true
end

.whitelisted?(field_expression) ⇒ Boolean

Returns:

  • (Boolean)


29
30
31
# File 'lib/better_newrelic_sql_obfuscator.rb', line 29

def whitelisted?(field_expression)
  WhitelistHash[field_expression]
end