58

Rails has built in log filtering so you don't log passwords and credit cards. Works great for that but when you want to trigger a custom log (like to email) and send your own params or other data along with it, the parameters are obviously not auto-filtered. I have been digging and trying to find this in the rails source but have had no luck so far.

I have configured rails to filter parameters as follows and it works properly for keeping the data out of rails logs:

config.filter_parameters += [:password, :password_confirmation, :credit_card]

How would you filter sensitive data from the params hash before dumping it into an email, api call or custom (non-rails) log?

lucapette
  • 20,564
  • 6
  • 65
  • 59
chrishomer
  • 4,900
  • 5
  • 38
  • 52

5 Answers5

74

Rails 4+

Sidenote for filtering the log in Rails 4+: The config.filter_parameters has been moved from application.rb to it's own initializer.

config/initializers/filter_parameter_logging.rb

Rails.application.config.filter_parameters += [:password]
davegson
  • 8,205
  • 4
  • 51
  • 71
  • 1
    Documented here: http://guides.rubyonrails.org/configuring.html#rails-general-configuration – Pistos Apr 30 '18 at 20:52
54

tadman answered correctly but here is some additional info:

In application.rb

config.filter_parameters += [:password, :password_confirmation, :credit_card]

Wherever you are doing custom logging:

f = ActionDispatch::Http::ParameterFilter.new(Rails.application.config.filter_parameters)
f.filter :order => {:credit_card => "4111111111111111"}

 => {:order=>{:credit_card=>"[FILTERED]"}} 
Brad Werth
  • 17,411
  • 10
  • 63
  • 88
chrishomer
  • 4,900
  • 5
  • 38
  • 52
  • 1
    It works but the recommended way to do that in Rails Apps are create a initializer file with the filter_parameters method. – lucianosousa Jun 05 '15 at 00:42
37

You can always use the except method:

params.except(:password, :password_confirmation, :credit_card)

That will exclude them from the listing. To "filter" them you could try this approach.

Community
  • 1
  • 1
tadman
  • 208,517
  • 23
  • 234
  • 262
21

If you are inside a rails controller method, why not just call request.filtered_parameters?

It is always a good choice to use what is already provided. Cheers!

Lester Celestial
  • 1,454
  • 1
  • 16
  • 26
  • 1
    This is actually should be the correct answer, thank you :) – Mohamed Sami Apr 30 '18 at 19:47
  • 1
    @MohamedSami How would this work? Calling `request.filtered_parameters.delete :fat_param` from the controller method doesn't seem to stop :fat_param from getting logged? – Crashalot Aug 26 '19 at 17:42
  • Thank you, I'm not if I remember why I wrote this? but I think for sure, it helped me somehow, thank you for your comment – Mohamed Sami Aug 27 '19 at 19:18
4

Just to add on @tadman answer:

When using except, beware that it will remove only top-level keys of your parameters, eg:

params = {
  search_query: 'foobar', 
  secret_key1: 'SENSITIVE_KEY_1', 
  auth_info: {secret_key_2: 'SENSITIVE_KEY2'}
}
params.except(:secret_key1, :secret_key2)

=> {:search_query=>"foobar", :auth_info=>{:secret_key_2=>"SENSITIVE_KEY2"}}

Using request.filtered_parameters will filter both of those keys if they are in config/application.rb

config.filter_parameters += [:password]
Benjamin Crouzier
  • 40,265
  • 44
  • 171
  • 236