Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork9.7k
[PasswordHasher] Make bcrypt nul byte hash test tolerant to PHP related failures#54858
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 ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Conversation
derrabus commentedMay 7, 2024
These tests already contain a PHP version detection logic for this purpose. Should we rather fix that instead of adding another layer? |
alexandre-daubois commentedMay 7, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
You mean adding |
xabbuh commentedMay 7, 2024
if (\PHP_VERSION_ID <80218 || \PHP_VERSION_ID >=80300 && \PHP_VERSION_ID <80305) {// password_hash() does not accept passwords containing NUL bytes since PHP 8.2.18 and 8.3.5$this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' =>4]),$plainPassword));} This part should probably be updated. |
alexandre-daubois commentedMay 7, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
But it is actually a bit different. In the part you highlight, we still try to hash+verify, whereas prior to 8.2, Checking However, changing from the annotation to an |
xabbuh commentedMay 7, 2024
This line should always be executed as our password hasher makes sure to not pass the nul byte to |
derrabus commentedMay 7, 2024
What puzzles me here: PHP 7.2 is around for a while already, why does this test start to become a problem just now? |
alexandre-daubois commentedMay 7, 2024
Ok I understand what I missed, I didn't see that the calls in |
xabbuh commentedMay 7, 2024
same for me, could it be that the Docker image that we use in the CI uses PHP versions that have patches backported? 🤔 |
alexandre-daubois commentedMay 7, 2024
Here is the commit responsible of the failure:php/php-src@11f2568 |
derrabus commentedMay 7, 2024
In that case, shall we drop the version detection entirely and make the test tolerant to the error raised by PHP? |
alexandre-daubois commentedMay 7, 2024
It seems that |
xabbuh commentedMay 7, 2024
for a job based on PHP 7.4.33 I would have expected to to have that same instruction appear inhttps://github.com/php/php-src/blob/PHP-7.4.33/ext/standard/password.c too |
xabbuh commentedMay 7, 2024
Nope, when a plain password contains nul it's always sha512 hashed and base 64 encoded (the same is also true if the password is longer than or equal to 72 characters no matter if it contains nul). |
derrabus commentedMay 7, 2024
Maybe@shivammathur can tell us if that patch has been backported to his PHP 7 builds. Sorry for the shameless ping. 😓 |
alexandre-daubois commentedMay 7, 2024
Oh yes my bad, nothing to do in the hasher indeed |
derrabus commentedMay 7, 2024
Answering my own question: Yes, the patch has been backported asshivammathur/php-src-backports@d22d9eb. Much love for this repository,@shivammathur. ❤️ In that case, I'm back to my proposal in#54858 (comment) |
xabbuh commentedMay 7, 2024
yes, makes sense to me then |
alexandre-daubois commentedMay 7, 2024
What do you think of this new approach? |
| try { | ||
| $verified =$hasher->verify($hasher->hash($plainPassword),$plainPassword); | ||
| $this->assertTrue($hasher->verify($hasher->hash($plainPassword),$plainPassword)); | ||
| $this->assertTrue($verified); | ||
| }catch (\ValueError$error) { |
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.
Please keep thetry block minimal and only include the call that you expect to raise theValueError. Given thatValueError is a very generic exception class, we should also sniff the exception message to make sure we're skipping the test for the right reasons.
Please also add a clarifying comment hinting at the PHP commit that caused this change.
I think, we should also skip the test for PHP >= 8.4 entirely (via annotation). This way, we can find and delete it once we open a branch that doesn't support PHP 8.3 anymore (likely Symfony 8.0).
| $this->assertTrue($hasher->verify($hasher->hash($plainPassword),$plainPassword)); | ||
| $this->assertTrue($verified); | ||
| }catch (\ValueError$error) { | ||
| $this->markTestSkipped(sprintf('password_hash() does not accept passwords containing NUL bytes on PHP %s.', \PHP_VERSION)); |
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->markTestSkipped(sprintf('password_hash() does not accept passwords containing NUL bytes on PHP %s.', \PHP_VERSION)); | |
| $this->markTestSkipped('password_hash() does not accept passwords containing NUL bytes.'); |
I would not include the current PHP version here.
5f131e3 toacb87acCompare| $this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' =>4]),$plainPassword)); | ||
| try { | ||
| $hash =password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' =>4]); | ||
| }catch (\ValueError$error) { |
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.
TheValueError error class does not exist on PHP 7. Please double check what the backport raises instead. Maybe catchingThrowable would be okay here, given that we filter out the exception message.
alexandre-dauboisMay 7, 2024 • edited
Loading Uh oh!
There was an error while loading.Please reload this page.
edited
Uh oh!
There was an error while loading.Please reload this page.
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.
I updated so we check for a Throwable with a specific message. I also checked the casepassword_hash() returns null, as implemented in the backport.
b748ada toc25c368Comparesrc/Symfony/Component/PasswordHasher/Tests/Hasher/NativePasswordHasherTest.phpShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
src/Symfony/Component/PasswordHasher/Tests/Hasher/NativePasswordHasherTest.php OutdatedShow resolvedHide resolved
Uh oh!
There was an error while loading.Please reload this page.
b1464b9 to89b2a2cComparexabbuh commentedMay 10, 2024
Thank you@alexandre-daubois. |
Bcrypt throws on PHP < 8.2 when passing a nul byte. The related test should be skipped for these versions as
$hasher->verify()return value cannot be asserted.Related failure:https://github.com/symfony/symfony/actions/runs/8980661047/job/24664698662#step:7:1168