Module: EzLogsAgent::Sanitizer
- Defined in:
- lib/ez_logs_agent/sanitizer.rb
Overview
Canonical sanitizer for “user-supplied data we’re about to ship over the wire”: HTTP params, GraphQL variables, and ActiveJob/Sidekiq arguments.
Rules:
-
Sensitive keys (password / token / secret / api_key / credit_card, plus user-configured patterns) are replaced with “[FILTERED]”.
-
Nested objects recurse up to MAX_NESTING_DEPTH (3); anything deeper collapses to “[Object]” so we never serialize unbounded graphs.
-
Arrays: small primitive arrays pass through; large ones (>5) collapse to a preview-plus-count string; arrays of objects are sanitized element-by-element with the same depth budget.
-
Non-primitive Ruby objects (anything not String/Numeric/Bool/nil) become “[Object]”. This protects us from accidentally serializing ActiveRecord instances or other big graphs that found their way into a job argument.
The module is pure (no I/O, no state), so it’s safe to call from any thread.
Constant Summary collapse
- SENSITIVE_PATTERNS =
Default sensitive-key patterns. Matched case-insensitively as SUBSTRINGS of the key, so ‘customer_password` matches `password`.
%w[ password passwd pwd token access_token refresh_token api_token auth_token secret api_secret client_secret api_key apikey private_key privatekey secret_key secretkey credential auth authorization encrypted encrypted_data ssn social_security credit_card card_number cvv cvc ].freeze
- MAX_NESTING_DEPTH =
Hard ceiling for nested object recursion. Deeper structures collapse to the literal string “[Object]”.
3- MAX_ARRAY_DISPLAY_SIZE =
Threshold above which an array is summarized instead of inlined. Below this size, primitive arrays are shipped verbatim; arrays of objects are mapped element-by-element.
5
Class Method Summary collapse
-
.sanitize_args(args) ⇒ Array
Sanitize an ordered list of job arguments (positional).
-
.sanitize_value(key, value, depth = 0) ⇒ Object
Sanitize a single key/value pair.
-
.sensitive_key?(key) ⇒ Boolean
Check whether a key matches a sensitive pattern.
Class Method Details
.sanitize_args(args) ⇒ Array
Sanitize an ordered list of job arguments (positional). Returns an Array with each element sanitized as if its index were the key (no sensitive-key match for integers — only the nested structure matters at the top level).
72 73 74 75 76 77 78 |
# File 'lib/ez_logs_agent/sanitizer.rb', line 72 def sanitize_args(args) return [] unless args.is_a?(Array) # Top-level array uses the same array-rules so giant arg lists # truncate to a preview-with-count rather than ship verbatim. sanitize_array_value(args, 0) end |
.sanitize_value(key, value, depth = 0) ⇒ Object
Sanitize a single key/value pair. Public entry point used by HTTP-param and job-arg sanitization.
54 55 56 57 58 59 60 61 62 63 |
# File 'lib/ez_logs_agent/sanitizer.rb', line 54 def sanitize_value(key, value, depth = 0) return "[FILTERED]" if sensitive_key?(key) return sanitize_nested_object(value, depth) if value.is_a?(Hash) return sanitize_array_value(value, depth) if value.is_a?(Array) return value if primitive?(value) # Anything else (AR records, dates, custom objects) collapses to # a placeholder so we never accidentally serialize a huge graph. "[Object]" end |
.sensitive_key?(key) ⇒ Boolean
Check whether a key matches a sensitive pattern. Public so the HTTP middleware can short-circuit early on identical keys.
85 86 87 88 89 90 91 92 93 94 |
# File 'lib/ez_logs_agent/sanitizer.rb', line 85 def sensitive_key?(key) key_lower = key.to_s.downcase return true if SENSITIVE_PATTERNS.any? { |pattern| key_lower.include?(pattern) } user_patterns = EzLogsAgent.configuration.excluded_graphql_variable_keys || [] user_patterns.any? { |pattern| key_lower.include?(pattern.to_s.downcase) } rescue # Defensive: when in doubt, treat as sensitive. true end |