diff --git a/CHANGELOG.md b/CHANGELOG.md index 529868b0..7c05a8c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,8 @@ Devise mappings be loaded during boot time (by @sidonath). * Added `Devise::Test::IntegrationHelpers` to bypass the sign in process using Warden test API (by @lucasmazza). + * Define `inspect` in `Devise::Models::Authenticatable` to help ensure password hashes + aren't included in exceptions or otherwise accidentally serialized (by @tkrajcar). * deprecations * `Devise::TestHelpers` is deprecated in favor of `Devise::Test::ControllerHelpers` (by @lucasmazza). diff --git a/lib/devise/models/authenticatable.rb b/lib/devise/models/authenticatable.rb index 567b230e..6f2f4fbb 100644 --- a/lib/devise/models/authenticatable.rb +++ b/lib/devise/models/authenticatable.rb @@ -114,6 +114,15 @@ module Devise super(options) end + # Redefine inspect using serializable_hash, to ensure we don't accidentally + # leak passwords into exceptions. + def inspect + inspection = serializable_hash.collect do |k,v| + "#{k}: #{respond_to?(:attribute_for_inspect) ? attribute_for_inspect(k) : v.inspect}" + end + "#<#{self.class} #{inspection.join(", ")}>" + end + protected def devise_mailer diff --git a/test/models/serializable_test.rb b/test/models/serializable_test.rb index 7e16f74f..6ced12d9 100644 --- a/test/models/serializable_test.rb +++ b/test/models/serializable_test.rb @@ -35,6 +35,11 @@ class SerializableTest < ActiveSupport::TestCase assert_key "confirmation_token", from_json(force_except: :email) end + test 'should not include unsafe keys in inspect' do + assert_match(/email/, @user.inspect) + assert_no_match(/confirmation_token/, @user.inspect) + end + def assert_key(key, subject) assert subject.key?(key), "Expected #{subject.inspect} to have key #{key.inspect}" end