Skip to content

Commit 6a8f23e

Browse files
Prevent leaking email addresses when user is not confirmed
A bad actor could exploit this vulnerability to see if a user exists in the system. Issues ------ - Closes #51
1 parent 0db991e commit 6a8f23e

File tree

3 files changed

+5
-4
lines changed

3 files changed

+5
-4
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ class SessionsController < ApplicationController
519519
@user = User.find_by(email: params[:user][:email].downcase)
520520
if @user
521521
if @user.unconfirmed?
522-
redirect_to new_confirmation_path, alert: "You must confirm your email before you can sign in."
522+
redirect_to new_confirmation_path, alert: "Incorrect email or password."
523523
elsif @user.authenticate(params[:user][:password])
524524
login @user
525525
redirect_to root_path, notice: "Signed in."
@@ -578,6 +578,7 @@ end
578578
> - The `create` method simply checks if the user exists and is confirmed. If they are, then we check their password. If the password is correct, we log them in via the `login` method we created in the `Authentication` Concern. Otherwise, we render an alert.
579579
> - We're able to call `user.authenticate` because of [has_secure_password](https://api.rubyonrails.org/classes/ActiveModel/SecurePassword/ClassMethods.html#method-i-has_secure_password)
580580
> - Note that we call `downcase` on the email to account for case sensitivity when searching.
581+
> - Note that we set the flash to "Incorrect email or password." if the user is unconfirmed. This prevents leaking email addresses.
581582
> - The `destroy` method simply calls the `logout` method we created in the `Authentication` Concern.
582583
> - The login form is passed a `scope: :user` option so that the params are namespaced as `params[:user][:some_value]`. This is not required, but it helps keep things organized.
583584
@@ -1324,7 +1325,7 @@ class SessionsController < ApplicationController
13241325
@user = User.authenticate_by(email: params[:user][:email].downcase, password: params[:user][:password])
13251326
if @user
13261327
if @user.unconfirmed?
1327-
redirect_to new_confirmation_path, alert: "You must confirm your email before you can sign in."
1328+
redirect_to new_confirmation_path, alert: "Incorrect email or password."
13281329
else
13291330
after_login_path = session[:user_return_to] || root_path
13301331
login @user

app/controllers/sessions_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ def create
66
@user = User.authenticate_by(email: params[:user][:email].downcase, password: params[:user][:password])
77
if @user
88
if @user.unconfirmed?
9-
redirect_to new_confirmation_path, alert: "You must confirm your email before you can sign in."
9+
redirect_to new_confirmation_path, alert: "Incorrect email or password."
1010
else
1111
after_login_path = session[:user_return_to] || root_path
1212
login @user

test/controllers/sessions_controller_test.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class SessionsControllerTest < ActionDispatch::IntegrationTest
6666
password: @unconfirmed_user.password
6767
}
6868
}
69-
assert_not_nil flash[:alert]
69+
assert_equal "Incorrect email or password.", flash[:alert]
7070
assert_nil current_user
7171
assert_redirected_to new_confirmation_path
7272
end

0 commit comments

Comments
 (0)