Don't use log level :debug in your production environments

Posted . Visible to the public.

Catch phrase

You don't want sensitive user data in your logs.

Background

Rails per default filters sensitive data like passwords and tokens and writes [FILTERED] to the logs. The code which is responsible for enabling that usually lives in filter_parameter_logging.rb (Rails.application.config.filter_parameters). Here is an example of a filtered log entry:

Unfiltered:
`User Load (0.4ms) SELECT "users".* FROM "users" WHERE "users"."token" = $1 LIMIT $2 [["token", "secret-token"], ["LIMIT", 1]]`

After the filter is applied:
`User Load (0.9ms) SELECT "users".* FROM "users" WHERE "users"."token" = $1 LIMIT $2 [["token", "[FILTERED]"], ["LIMIT", 1]]`

Unfortunately, this mechanism is not always applied, because of code dependencies. Some are written by us (the project maintainers), some come from gems which we don't have control of.

Solutions

  • Don't log SQL queries. This is the default behavior of rails but can be changed in the config/environment/production.rb file:
    config.log_level should not be set to :debug, but to :info or just be omitted.
  • Make sure that your custom logger does not log secrets, if you're using one.
  • Add this file to your config/initializers, it fixes the loading order issue but will only work for Rails >= 6:
# fix_active_record_filter_attributes.rb

# We're loading ActiveRecord before `filter_parameter_logging.rb` has run and thus Rails sets AR::Base.filter_attributes = []
# This forces us to set the filter_attributes again to avoid logging PII in SQL queries
ActiveSupport.on_load(:active_record) do
  Rails.application.config.after_initialize do
    ActiveRecord::Base.filter_attributes = Rails.application.config.filter_parameters
  end
end
Jakob Scholz
Last edit
Jakob Scholz
License
Source code in this card is licensed under the MIT License.
Posted by Jakob Scholz to makandra dev (2023-09-21 06:46)