-
Notifications
You must be signed in to change notification settings - Fork 21.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add inspection_masks
to make values of sensitive database columns w…
#33756
Conversation
@@ -8,6 +8,8 @@ module ActiveRecord | |||
module Core | |||
extend ActiveSupport::Concern | |||
|
|||
FILTERED = "[FILTERED]".freeze # :nodoc: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't need to freeze this string.
Hi @rafaelfranca , I have removed |
This is great! I'm wondering though, would it be better to piggyback on the |
Hi @eileencodes , thanks for your advise, I checked in a new commit based on your comment. I don't know how to write test about |
trigger CI |
@piecehealth you should be able to add a test to railties/test/application/configuration_test.rb that asserts that inspection_masks are equivalent to filter_parameters. I'm not sure if |
I agree it'd be better to have them sound more related. My only worry about We definitely also need to cover Finally, on a behavioural note: I suggest we do not mask the value if it's nil (or maybe blank?). |
Thanks @eileencodes @matthewd for your review, I have made some changes according your comments.
By the way, it's really hard for non English speaker to name variable 😢 |
@@ -487,12 +493,17 @@ def connection_handler | |||
|
|||
# Returns the contents of the record as a nicely formatted string. | |||
def inspect | |||
filter_attributes = self.filter_attributes.map(&:to_s) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this will have include?
called on it for each attribute in the model, I think we should convert it to a set (include?
is linear time for an array, but constant time for a set).
It might also be worth doing the conversion on assignment, as we do for ignored_columns
:
rails/activerecord/lib/active_record/model_schema.rb
Lines 274 to 276 in e6ba30e
def ignored_columns=(columns) | |
@ignored_columns = columns.map(&:to_s) | |
end |
@@ -235,5 +235,13 @@ class Railtie < Rails::Railtie # :nodoc: | |||
end | |||
end | |||
end | |||
|
|||
initializer "active_record.set_filter_attributes" do | |||
config.after_initialize do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is unnecessary, and in fact it causes a problem: if the user sets filter_attributes
in an initializer, their configuration will be overwritten by filter_parameters
and lost.
It might be worth adding a test for this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your valuable advice, I just wonder is it necessary for user to set filter_attributes
in an initializer? Since user could set filter_attributes
in ApplicationRecord
e.g.
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
self.filter_attributes = [:credit_card_number]
end
Otherwise, I should add a new instance variable @filter_attributes
in Rails::Application::Configuration
, please correct me if there is any mistake, thanks 😉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any option on ActiveRecord::Base
can be configured by setting a key on Rails.application.config.active_record
. I was thinking of someone adding an initializer that mirrors the one for filter_parameters
, since they're so similar:
initializer "active_record.set_filter_attributes" do | ||
config.after_initialize do | ||
ActiveSupport.on_load(:active_record) do | ||
ActiveRecord::Base.filter_attributes = Rails.application.config.filter_parameters |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These hooks are run in the context of ActiveRecord::Base
, and it's idiomatic to use self
instead of referring to the constant explicitly, e.g:
rails/activerecord/lib/active_record/railtie.rb
Lines 135 to 137 in e6ba30e
initializer "active_record.initialize_database" do | |
ActiveSupport.on_load(:active_record) do | |
self.configurations = Rails.application.config.database_configuration |
000983c
to
2f7220a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome! Very good patch. Can you squash your commit?
…ensitive value of database column when call `#inspect` * Why Some sensitive data will be exposed in log accidentally by calling `#inspect`, e.g. ```ruby @account = Account.find params[:id] payload = { account: @account } logger.info "payload will be #{ payload }" ``` All the information of `@account` will be exposed in log. * Solution Add a class attribute filter_attributes to specify which values of columns shouldn't be exposed. This attribute equals to `Rails.application.config.filter_parameters` by default. ```ruby Rails.application.config.filter_parameters += [:credit_card_number] Account.last.insepct # => #<Account id: 123, credit_card_number: [FILTERED] ...> ```
@rafaelfranca @eileencodes thanks for your time, I have squashed my commits and the CI is passed 😃 |
Add mention that `config.filter_parameters` also filters out sensitive values of database columns when call `#inspect` since rails#33756.
- Move ``` filter_attributes = self.filter_attributes.map(&:to_s).to_set filter_attributes.include?(attribute_name) && !read_attribute(attribute_name).nil? ``` to private method. - Fix tests in `activerecord/test/cases/filter_attributes_test.rb` - Ensure that `teardown` sets `ActiveRecord::Base.filter_attributes` to previous state. - Ensure that `Admin::Account.filter_attributes` is set to previous state in the "filter_attributes could be overwritten by models" test. Follow up rails#33756
Pleased to see this, lovely addition 👍 Currently it will behave inconsistently for apps configured with regex or callable For those apps, affected request parameters successfully filtered in the logs will not be filtered in Related examples from
|
can this be used or improved for |
AR instance support `filter_parameters` since rails#33756. Though Regex or Proc is valid as `filter_parameters`, they are not supported as AR#inspect. I also add :mask option and #filter_params to `ActiveSupport::ParameterFilter#new` to implement this.
Configuration item config.filter_parameters could also filter out sensitive values of database columns when call #inspect rails/rails#33756
Configuration item config.filter_parameters could also filter out sensitive values of database columns when call #inspect rails/rails#33756
Also, is there any chance that this will make it into a security patch for 5.2? |
Nope, we don't backport features even when they're security related. Security patches are only for vulnerabilities. |
…on't be exposed while call
#inspect
.Some sensitive data will be exposed in log accidentally, e.g.
All the information of
account
will be exposed in log.Add a class attribute
inspection_masks
to specify which values of columns shouldn't be exposed.Summary
Provide a general description of the code changes in your pull
request... were there any bugs you had fixed? If so, mention them. If
these bugs have open GitHub issues, be sure to tag them here as well,
to keep the conversation linked together.
Other Information
If there's anything else that's important and relevant to your pull
request, mention that information here. This could include
benchmarks, or other information.
If you are updating any of the CHANGELOG files or are asked to update the
CHANGELOG files by reviewers, please add the CHANGELOG entry at the top of the file.
Finally, if your pull request affects documentation or any non-code
changes, guidelines for those changes are available
here
Thanks for contributing to Rails!