Summary
Rollbar::Scrubbers::Params#scrub uses value.is_a?(Hash) to decide whether to recurse into nested structures. Objects that implement Ruby's implicit to_hash conversion but are not Hash subclasses — such as Rails'
ActionController::Parameters, are silently skipped. Their internal keys and values pass through completely unscrubbed, leaking credentials that scrub_fields would otherwise catch.
Environment
rollbar-gem: all versions through v3.8.0 (issue present on master)
- Affected:
ActionController::Parameters (Rails 5+), any object with to_hash that is not a Hash subclass
Reproduction
require "action_controller"
params = ActionController::Parameters.new(
username: "user@example.com",
password: "s3cret123"
).permit(:username, :password)
# scrub_fields defaults include :password
result = Rollbar::Scrubbers::Params.call(
params: { body: params },
config: Rollbar.configuration.scrub_fields
)
result[:body][:password] # => "s3cret123" — NOT scrubbed
Real-world trigger: a Rails controller calls an external API via a service object. The request body (ActionController::Parameters from params.permit) is included in extra data passed to Rollbar.warning. When the API call fails, credentials
appear in plaintext in the Rollbar dashboard.
line 82
elsif value.is_a?(Hash)
scrub(value, options)
ActionController::Parameters (since Rails 5) does not inherit from Hash. is_a?(Hash) returns false, so the entire body is treated as an opaque scalar — all keys and values pass through unscrubbed.
The same gap exists in scrub_array at line 100:
line 100
value.is_a?(Hash) ? scrub(value, options) : rollbar_filtered_param_value(value)
Suggested Fix
Use Ruby's to_hash implicit conversion protocol to identify Hash-like objects:
+ def hash_like?(value)
+ value.is_a?(Hash) || value.respond_to?(:to_hash)
+ end
def scrub(params, options)
...
- elsif value.is_a?(Hash)
- scrub(value, options)
+ elsif hash_like?(value)
+ scrub(value.is_a?(Hash) ? value : value.to_hash, options)
...
end
def scrub_array(array, options)
array.map do |value|
- value.is_a?(Hash) ? scrub(value, options) : rollbar_filtered_param_value(value)
+ hash_like?(value) ? scrub(value.is_a?(Hash) ? value : value.to_hash, options) : rollbar_filtered_param_value(value)
end
end
Why to_hash over to_h
to_hash is Ruby's implicit conversion protocol, only objects that genuinely signal "I am a Hash" implement it. to_h is broader: Array#to_h exists (Ruby 2.6+) and arrays must continue through scrub_array, not scrub.
Impact
Any Rails app that passes ActionController::Parameters through to an external API client will leak credentials, tokens, or other sensitive data into Rollbar when the API call fails. The scrub_fields configuration (which already includes
password, secret, token by default) silently has no effect on these objects.
Summary
Rollbar::Scrubbers::Params#scrubusesvalue.is_a?(Hash)to decide whether to recurse into nested structures. Objects that implement Ruby's implicitto_hashconversion but are notHashsubclasses — such as Rails'ActionController::Parameters, are silently skipped. Their internal keys and values pass through completely unscrubbed, leaking credentials thatscrub_fieldswould otherwise catch.Environment
rollbar-gem: all versions through v3.8.0 (issue present onmaster)ActionController::Parameters(Rails 5+), any object withto_hashthat is not aHashsubclassReproduction
Real-world trigger: a Rails controller calls an external API via a service object. The request body (ActionController::Parameters from params.permit) is included in extra data passed to Rollbar.warning. When the API call fails, credentials
appear in plaintext in the Rollbar dashboard.
line 82
elsif value.is_a?(Hash)
scrub(value, options)
ActionController::Parameters (since Rails 5) does not inherit from Hash. is_a?(Hash) returns false, so the entire body is treated as an opaque scalar — all keys and values pass through unscrubbed.
The same gap exists in scrub_array at line 100:
line 100
value.is_a?(Hash) ? scrub(value, options) : rollbar_filtered_param_value(value)
Suggested Fix
Use Ruby's to_hash implicit conversion protocol to identify Hash-like objects:
Why to_hash over to_h
to_hash is Ruby's implicit conversion protocol, only objects that genuinely signal "I am a Hash" implement it. to_h is broader: Array#to_h exists (Ruby 2.6+) and arrays must continue through scrub_array, not scrub.
Impact
Any Rails app that passes ActionController::Parameters through to an external API client will leak credentials, tokens, or other sensitive data into Rollbar when the API call fails. The scrub_fields configuration (which already includes
password, secret, token by default) silently has no effect on these objects.