Skip to content

Commit

Permalink
Make reset password, unlock account, and verify account pages not lea…
Browse files Browse the repository at this point in the history
…k keys to external servers via Referer header

These changes are based in spirit on changes made to Clearance.

No spec changes necessary for this, so it should be backwards
compatible.
  • Loading branch information
jeremyevans committed Nov 16, 2016
1 parent dfe852d commit 18f2648
Show file tree
Hide file tree
Showing 10 changed files with 41 additions and 11 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
=== HEAD

* Make reset password, unlock account, and verify account pages not leak keys to external servers via Referer header (jeremyevans)

=== 1.6.0 (2016-10-24)

* Add http_basic_auth feature (TiagoCardoso1983, jeremyevans) (#12)
Expand Down
1 change: 1 addition & 0 deletions doc/lockout.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ unlock_account_requires_password? :: Whether a password is required when unlocki
false by default. May want to set to true if not
allowing password resets.
unlock_account_route :: Alias for lockout_route.
unlock_account_session_key :: The key in the session to hold the unlock account key temporarily.

== Auth Methods

Expand Down
1 change: 1 addition & 0 deletions doc/reset_password.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ reset_password_request_error_flash :: The flash error to show if not able to sen
password email.
reset_password_request_route :: The route to the reset password request action.
reset_password_route :: The route to the reset password action.
reset_password_session_key :: The key in the session to hold the reset password key temporarily.
reset_password_table :: The name of the reset password keys table.

== Auth Methods
Expand Down
1 change: 1 addition & 0 deletions doc/verify_account.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ verify_account_resend_error_flash :: The flash error to show if unable to resend
verify account email.
verify_account_resend_route :: The route to the verify account resend action.
verify_account_route :: The route to the verify account action.
verify_account_session_key :: The key in the session to hold the verify account key temporarily.
verify_account_table :: The name of the verify account keys table.

== Auth Methods
Expand Down
22 changes: 16 additions & 6 deletions lib/rodauth/features/lockout.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ module Rodauth
auth_value_method :unlock_account_email_subject, 'Unlock Account'
auth_value_method :unlock_account_key_param, 'key'
auth_value_method :unlock_account_requires_password?, false
auth_value_method :unlock_account_session_key, :unlock_account_key

auth_value_methods(
:unlock_account_redirect,
Expand Down Expand Up @@ -81,16 +82,24 @@ module Rodauth
before_unlock_account_route

r.get do
if account_from_unlock_key(param(unlock_account_key_param))
unlock_account_view
else
set_redirect_error_flash no_matching_unlock_account_key_message
redirect require_login_redirect
if key = param_or_nil(unlock_account_key_param)
session[unlock_account_session_key] = key
redirect(r.path)
end

if key = session[unlock_account_session_key]
if account_from_unlock_key(key)
unlock_account_view
else
session[unlock_account_session_key] = nil
set_redirect_error_flash no_matching_unlock_account_key_message
redirect require_login_redirect
end
end
end

r.post do
key = param(unlock_account_key_param)
key = session[unlock_account_session_key] || param(unlock_account_key_param)
unless account_from_unlock_key(key)
set_redirect_error_flash no_matching_unlock_account_key_message
redirect unlock_account_request_redirect
Expand All @@ -106,6 +115,7 @@ module Rodauth
end
end

session[unlock_account_session_key] = nil
set_notice_flash unlock_account_notice_flash
redirect unlock_account_redirect
else
Expand Down
10 changes: 9 additions & 1 deletion lib/rodauth/features/reset_password.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ module Rodauth
auth_value_method :reset_password_table, :account_password_reset_keys
auth_value_method :reset_password_id_column, :id
auth_value_method :reset_password_key_column, :key
auth_value_method :reset_password_session_key, :reset_password_key

auth_value_methods :reset_password_email_sent_redirect

Expand Down Expand Up @@ -76,17 +77,23 @@ module Rodauth

r.get do
if key = param_or_nil(reset_password_key_param)
session[reset_password_session_key] = key
redirect(r.path)
end

if key = session[reset_password_session_key]
if account_from_reset_password_key(key)
reset_password_view
else
session[reset_password_session_key] = nil
set_redirect_error_flash no_matching_reset_password_key_message
redirect require_login_redirect
end
end
end

r.post do
key = param(reset_password_key_param)
key = session[reset_password_session_key] || param(reset_password_key_param)
unless account_from_reset_password_key(key)
set_redirect_error_flash reset_password_error_flash
redirect reset_password_email_sent_redirect
Expand Down Expand Up @@ -117,6 +124,7 @@ module Rodauth
update_session
end

session[reset_password_session_key] = nil
set_notice_flash reset_password_notice_flash
redirect reset_password_redirect
end
Expand Down
10 changes: 9 additions & 1 deletion lib/rodauth/features/verify_account.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ module Rodauth
auth_value_method :verify_account_table, :account_verification_keys
auth_value_method :verify_account_id_column, :id
auth_value_method :verify_account_key_column, :key
auth_value_method :verify_account_session_key, :verify_account_key

auth_value_methods :verify_account_key_value

Expand Down Expand Up @@ -76,17 +77,23 @@ module Rodauth

r.get do
if key = param_or_nil(verify_account_key_param)
session[verify_account_session_key] = key
redirect(r.path)
end

if key = session[verify_account_session_key]
if account_from_verify_account_key(key)
verify_account_view
else
session[verify_account_session_key] = nil
set_redirect_error_flash no_matching_verify_account_key_message
redirect require_login_redirect
end
end
end

r.post do
key = param(verify_account_key_param)
key = session[verify_account_session_key] || param(verify_account_key_param)
unless account_from_verify_account_key(key)
set_redirect_error_flash verify_account_error_flash
redirect verify_account_redirect
Expand All @@ -103,6 +110,7 @@ module Rodauth
update_session
end

session[verify_account_session_key] = nil
set_notice_flash verify_account_notice_flash
redirect verify_account_redirect
end
Expand Down
1 change: 0 additions & 1 deletion templates/reset-password.str
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<form method="post" class="rodauth form-horizontal" role="form" id="reset-password-form">
#{rodauth.reset_password_additional_form_tags}
<input type="hidden" name="#{rodauth.reset_password_key_param}" value="#{h request[rodauth.reset_password_key_param]}" />
#{rodauth.csrf_tag}
#{rodauth.render('password-field')}
#{rodauth.render('password-confirm-field') if rodauth.require_password_confirmation?}
Expand Down
1 change: 0 additions & 1 deletion templates/unlock-account.str
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
<form method="post" class="rodauth form-horizontal" role="form" id="unlock-account-form">
#{rodauth.unlock_account_additional_form_tags}
#{rodauth.csrf_tag}
<input type="hidden" name="#{rodauth.unlock_account_key_param}" value="#{h request[rodauth.unlock_account_key_param]}"/>
<p>This account is currently locked out. You can unlock the account.</p>
#{rodauth.render('password-field') if rodauth.unlock_account_requires_password?}
#{rodauth.button(rodauth.unlock_account_button)}
Expand Down
1 change: 0 additions & 1 deletion templates/verify-account.str
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<form method="post" class="rodauth form-horizontal" role="form" id="verify-account-form">
#{rodauth.verify_account_additional_form_tags}
<input type="hidden" name="#{rodauth.verify_account_key_param}" value="#{h request[rodauth.verify_account_key_param]}" />
#{rodauth.csrf_tag}
#{rodauth.button(rodauth.verify_account_button)}
</form>
Expand Down

0 comments on commit 18f2648

Please sign in to comment.