Skip to content

Commit

Permalink
Work around implicit null byte check added in bcrypt 3.1.18 by checki…
Browse files Browse the repository at this point in the history
…ng password requirements before other password checks

An undocumented change in bcrypt 3.1.18 causes it to raise
ArgumentError for passwords with null bytes, due to a change to
use StringValueCStr instead of StringValuePtr in the change to
unlock the GVL while calculating the password hash.

This works around the issue by performing Rodauth's checks on the
password before passing the password to bcrypt.
  • Loading branch information
jeremyevans committed May 23, 2022
1 parent dd74d52 commit ee89ecb
Show file tree
Hide file tree
Showing 3 changed files with 7 additions and 5 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
=== master

* Work around implicit null byte check added in bcrypt 3.1.18 by checking password requirements before other password checks (jeremyevans)

* Fix invalid HTML on pages with OTP QR codes (jeremyevans)

* Add recovery_codes_available? configuration method to the recovery_codes feature (janko) (#238)
Expand Down
8 changes: 4 additions & 4 deletions lib/rodauth/features/reset_password.rb
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,10 @@ module Rodauth

password = param(password_param)
catch_error do
unless password_meets_requirements?(password)
throw_error_status(invalid_field_error_status, password_param, password_does_not_meet_requirements_message)
end

if password_match?(password)
throw_error_reason(:same_as_existing_password, invalid_field_error_status, password_param, same_as_existing_password_message)
end
Expand All @@ -138,10 +142,6 @@ module Rodauth
throw_error_reason(:passwords_do_not_match, unmatched_field_error_status, password_param, passwords_do_not_match_message)
end

unless password_meets_requirements?(password)
throw_error_status(invalid_field_error_status, password_param, password_does_not_meet_requirements_message)
end

transaction do
before_reset_password
set_password(password)
Expand Down
2 changes: 1 addition & 1 deletion spec/reset_password_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ def rodauth.raised_uniqueness_violation(*) StandardError.new; end
res = json_request('/reset-password', :key=>link[4...-1])
res.must_equal [401, {"reason"=>"invalid_reset_password_key", "error"=>"There was an error resetting your password"}]

res = json_request('/reset-password', :key=>link[4..-1], :password=>'1', "password-confirm"=>'2')
res = json_request('/reset-password', :key=>link[4..-1], :password=>'ab1234561', "password-confirm"=>'ab1234562')
res.must_equal [422, {'reason'=>"passwords_do_not_match","error"=>"There was an error resetting your password", "field-error"=>["password", 'passwords do not match']}]

res = json_request('/reset-password', :key=>link[4..-1], :password=>'0123456789', "password-confirm"=>'0123456789')
Expand Down

0 comments on commit ee89ecb

Please sign in to comment.