chrishomer
chrishomer

Reputation: 4920

How to filter parameters in rails?

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?

Upvotes: 59

Views: 62224

Answers (6)

AliceTheCat
AliceTheCat

Reputation: 300

In addition to tadman's answer you can also use permit to whitelist parameters

params.permit(:whitelisted_parameter)

with this only whitelisted_parameter will be in the returning object.

https://apidock.com/rails/v7.1.3.2/ActionController/Parameters/permit

Upvotes: 0

davegson
davegson

Reputation: 8331

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]

Upvotes: 78

Benjamin Crouzier
Benjamin Crouzier

Reputation: 41965

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]

Upvotes: 4

Lester Celestial
Lester Celestial

Reputation: 1484

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!

Upvotes: 23

chrishomer
chrishomer

Reputation: 4920

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]"}} 

Upvotes: 54

tadman
tadman

Reputation: 211740

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.

Upvotes: 37

Related Questions