In our application we want to filter certain parameters differently depending on their usage... for example passwords should always be filtered entirely, but for email and name we want to retain parts of the value for debugging and support.
To do this, we've used a custom proc to format them:
1_filter_parameter_logging.rb:
Rails.application.config.filter_parameters += [
:password
]
Rails.application.config.filter_parameters << proc do |param_name, value|
if %w[email name].include?(param_name)
if param_name.to_s == 'email'
value.gsub!(/(?<=^.{2}).*?(?=@)/, '*') # test partial filter
else
value.replace('[FILTERED_CUSTOM]') # test custom filter
end
end
end
Then in 2_airbrake.rb we use these settings as so:
c.blacklist_keys = Rails.application.config.filter_parameters
To test this theory, we deliberately throw an exception in our app with this example controller action:
class ExampleController
def show
raise StandardError, 'Testing Filter Parameter Logging'
end
end
And then make a simple request to that endpoint:
http://localhost:3000/example?name=cameron&[email protected]&password=test
In our logs we see the following:
Processing by ExampleController#show as HTML
Parameters: {"name"=>"[FILTERED_CUSTOM]", "email"=>"ca*@test.com", "password"=>"[FILTERED]"}
And then an error from Airbake:
**Airbrake: one of the patterns in Airbrake::Filters::KeysBlacklist is invalid. Known patterns: [:password, nil]
And if we look at the error in Airbrake we see that it hasn't filtered them:
{
"action" => "show",
"controller" => "example",
"email" => "[email protected]",
"name" => "cameron",
"password" => "[Filtered]"
}
Why is Airbrake throwing that error, seems Rails is able to filter those parameters using that proc based on those logs, but then Airbrake fails to filter them and allows them through.
Airbrake doesn't explain exactly what's invalid with the pattern... just that it doesn't see it as valid, which isn't very helpful.
The param filtering offered by Rails is different than Airbrake.
Rails allows for complex param filtering. You can define a
procthat takes in the parameterkeyandvalueas arguments and returns the filtered value. The execution of theprochappens here inActiveSupport::ParameterFilter#value_for_key.Airbrake is more limited. It can only filter parameter names by comparing them against a String, Symbol, or Regexp. The documentation indicates that you can define a
procbut it only gets executed once on the first notification and:The
procis executed here. It is called without any arguments. If your exampleprocis called without arguments it returnsnil. Since this doesn't match a String, Symbol, or Regexp an exception is raised here.Airbrake uses a
should_filter?method that takes just the paramkey. If that method returnstruethe"[Filtered]"string replaces the value. This existing structure isn't easy to quickly override to get the behavior you want. But you could try to completely override theAirbrake::Filters::KeysBlocklistclass andAirbrake::Filters::KeysFiltermodule.Note that the info here and all the links are for the current version of
airbrake-ruby.blacklist_keyswas replaced byblocklist_keysseveral years ago. And classes likeKeysBlacklistwere replaced byKeysBlocklist. But these were just naming changes and functionality has remained relatively the same over time.Rather than override the standard Airbrake param filtering, you're probably better off trying to add a custom filter. Here's an example of what you could try to put into an initializer in your app: