Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

[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

Merged
xabbuh merged 1 commit intosymfony:5.4fromalexandre-daubois:bcrypt-throws
May 10, 2024

Conversation

@alexandre-daubois
Copy link
Member

QA
Branch?5.4
Bug fix?yes
New feature?no
Deprecations?no
Issues-
LicenseMIT

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

@derrabus
Copy link
Member

These tests already contain a PHP version detection logic for this purpose. Should we rather fix that instead of adding another layer?

@alexandre-daubois
Copy link
MemberAuthor

alexandre-daubois commentedMay 7, 2024
edited
Loading

You mean addingif (\PHP_VERSION_ID < 80200) { $this->markAsSkipped(...); } at the top of the test instead of having the annotation ?

@xabbuh
Copy link
Member

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
Copy link
MemberAuthor

alexandre-daubois commentedMay 7, 2024
edited
Loading

But it is actually a bit different. In the part you highlight, we still try to hash+verify, whereas prior to 8.2,password_hash() directly throws.$hasher->verify() is then skipped. Because of this, it doesn't seems relevant to me to trigger the test before PHP 8.2. 🤔

Checkingpassword_hash() actually throws something would be the same as testing the function itself, which is probably already done somewhere in the PHP engine.

However, changing from the annotation to anif statement at the beginning of the test case suits me fine 🙂

@xabbuh
Copy link
Member

$this->assertTrue($hasher->verify($hasher->hash($plainPassword), $plainPassword));

This line should always be executed as our password hasher makes sure to not pass the nul byte topassword_hash(). That's why we have theif. I actually do not really understand why the PHP 7.2 and 7.4 suddenly fail as the changes in PHP I referenced in#54587 did not happen on these versions. 🤔

derrabus reacted with heart emoji

@derrabus
Copy link
Member

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
Copy link
MemberAuthor

Ok I understand what I missed, I didn't see that the calls inassertFalse() andassertTrue() were different 🤦 I'll investigate a bit more and reopen something when I have the right fix

@xabbuh
Copy link
Member

What puzzles me here: PHP 7.2 is around for a while already, why does this test start to become a problem just now?

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
Copy link
MemberAuthor

Here is the commit responsible of the failure:php/php-src@11f2568

@derrabus
Copy link
Member

same for me, could it be that the Docker image that we use in the CI uses PHP versions that have patches backported? 🤔

In that case, shall we drop the version detection entirely and make the test tolerant to the error raised by PHP?

@alexandre-daubois
Copy link
MemberAuthor

It seems thatpassword_hash() doesn't support\0 at all now. ShouldNativePasswordHasher but updated to forbid the nul char? Currently, it allows it if the password is more than 72 chars long

@xabbuh
Copy link
Member

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
Copy link
Member

Currently, it allows it if the password is more than 72 chars long

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
Copy link
Member

Maybe@shivammathur can tell us if that patch has been backported to his PHP 7 builds. Sorry for the shameless ping. 😓

alexandre-daubois reacted with thumbs up emoji

@alexandre-daubois
Copy link
MemberAuthor

when a plain password contains nul it's always sha512 hashed and base 64 encoded

Oh yes my bad, nothing to do in the hasher indeed

@derrabus
Copy link
Member

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)

alexandre-daubois, xabbuh, and shivammathur reacted with thumbs up emoji

@xabbuh
Copy link
Member

In that case, shall we drop the version detection entirely and make the test tolerant to the error raised by PHP?

yes, makes sense to me then

alexandre-daubois reacted with eyes emoji

@alexandre-dauboisalexandre-daubois changed the title[PasswordHasher] Skip test on nul byte for PHP versions that doesn't support it with Bcrypt[PasswordHasher] Make bcrypt nul byte hash test tolerant to PHP related failuresMay 7, 2024
@alexandre-daubois
Copy link
MemberAuthor

What do you think of this new approach?

Comment on lines 106 to 111
try {
$verified =$hasher->verify($hasher->hash($plainPassword),$plainPassword);

$this->assertTrue($hasher->verify($hasher->hash($plainPassword),$plainPassword));
$this->assertTrue($verified);
}catch (\ValueError$error) {
Copy link
Member

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).

alexandre-daubois reacted with eyes emoji
$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));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

Suggested change
$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.

alexandre-daubois reacted with thumbs up emoji
@alexandre-dauboisalexandre-dauboisforce-pushed thebcrypt-throws branch 2 times, most recently from5f131e3 toacb87acCompareMay 7, 2024 10:02
$this->assertFalse($hasher->verify(password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' =>4]),$plainPassword));
try {
$hash =password_hash($plainPassword, \PASSWORD_BCRYPT, ['cost' =>4]);
}catch (\ValueError$error) {
Copy link
Member

@derrabusderrabusMay 7, 2024
edited
Loading

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.

Copy link
MemberAuthor

@alexandre-dauboisalexandre-dauboisMay 7, 2024
edited
Loading

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.

@alexandre-dauboisalexandre-dauboisforce-pushed thebcrypt-throws branch 4 times, most recently fromb748ada toc25c368CompareMay 7, 2024 11:29
@xabbuh
Copy link
Member

Thank you@alexandre-daubois.

@xabbuhxabbuh merged commit6750f6c intosymfony:5.4May 10, 2024
@xabbuhxabbuh mentioned this pull requestMay 14, 2024
Sign up for freeto join this conversation on GitHub. Already have an account?Sign in to comment

Reviewers

@derrabusderrabusderrabus approved these changes

@xabbuhxabbuhxabbuh approved these changes

@chalasrchalasrAwaiting requested review from chalasrchalasr is a code owner

Assignees

No one assigned

Projects

None yet

Milestone

5.4

Development

Successfully merging this pull request may close these issues.

4 participants

@alexandre-daubois@derrabus@xabbuh@carsonbot

[8]ページ先頭

©2009-2025 Movatter.jp