[go: nahoru, domu]

Skip to content
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 our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Always use PHP's own crypt_r implementation, don't support system crypt #5761

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

alexdowad
Copy link
Contributor

Looking forward to hearing your comments.

@alexdowad
Copy link
Contributor Author

Failure on Appveyor looks to be spurious.

@nikic
Copy link
Member
nikic commented Jun 24, 2020

Feel free to land everything but the last commit already.

@alexdowad
Copy link
Contributor Author

Feel free to land everything but the last commit already.

I did think the last commit would be more controversial than the others. 😄

@nikic
Copy link
Member
nikic commented Jun 24, 2020

For the last commit, I have some concerns:

  • man 5 crypt lists at least two algorithms we don't support: $y$ (yescript) and $7$ (scrypt).
  • PHP has some bcrypt related weirdness, because it supports $2x$ and $2y$ prefixes. There may be some behavior discrepancy with glibc here.

@nikic
Copy link
Member
nikic commented Jun 24, 2020

So, now I'm left wondering what actually happens if we use the glibc implementation, wrt to $2y$.

My current state is that we probably never use the glibc implementation, because $php_crypt_r gets set to 0, because the function is checked in the wrong library (and later in the correct library).

@nikic
Copy link
Member
nikic commented Jun 24, 2020

I've applied 7d05bc8 to fix the crypt_r detection, and instead added a || true to the code picking the implementation, so it's a bit more honest about what's going on :)

@nikic
Copy link
Member
nikic commented Jun 24, 2020

I've also fixed one behavior difference in 4c4af2b (landed this one in 7.4).

There's a diff in ext/standard/tests/strings/crypt_sha256.phpt:

Iteration 8 failed.
Expected: <$5$rounds=1000$roundstoolow$yfvwcWrQ8l/K0DAWyuPMDNHpIVlTQebY9l/gL972bIC>
Got       <*0>
Passes.

It looks like we aren't rejecting overly low rounds.

@nikic
Copy link
Member
nikic commented Jun 24, 2020

I've addressed that discrepancy with 8a8c8d4.

@nikic
Copy link
Member
nikic commented Jun 24, 2020

Regarding the last commit, I think we should be supporting system crypt as the fallback implementation for all the hashes we don't know. That's not how it works right now, but I think that's how it should work.

@alexdowad
Copy link
Contributor Author

For the last commit, I have some concerns:

  • man 5 crypt lists at least two algorithms we don't support: $y$ (yescript) and $7$ (scrypt).
  • PHP has some bcrypt related weirdness, because it supports $2x$ and $2y$ prefixes. There may be some behavior discrepancy with glibc here.

...

Regarding the last commit, I think we should be supporting system crypt as the fallback implementation for all the hashes we don't know. That's not how it works right now, but I think that's how it should work.

I have a different view.

Users don't care about libc or what hashes it supports. (Many PHP users probably don't even know what libc is.) Users definitely do not want their programs to fail when moved from a dev machine to a server, or from one server to another, because a different version of glibc is installed there.

It is better not to create unnecessary dependencies on the underlying system libraries. We need to use system APIs to access the hardware or modify the system state. But where just pure computation is involved, it almost never makes sense to rely on them.

If glibc supports some hashes which PHP doesn't know about, I would be happy to implement them.

PHP contains a (presumably) correct, portable, and efficient implementation of
`crypt_r` hashing, including all the possible hash algorithms which libc's
`crypt_r` may possibly implement.

Since this is so, why should we test for the platform `crypt_r` and only use
our own implementation if it's not there? What benefit could there be from
using libc's `crypt_r`? Maybe it might be faster? If so, PHP's implementation
can be optimized. There is nothing "magic" which libc can do and which PHP
can't do.

If we didn't have a full implementation, it would make sense to take advantage
of the one in libc, but since we do, this is just complicating things.
@alexdowad
Copy link
Contributor Author

By the way, @nikic, thanks for finding those other problems with PHP's crypt_r. 👍

@nikic
Copy link
Member
nikic commented Jun 24, 2020

Regarding the last commit, I think we should be supporting system crypt as the fallback implementation for all the hashes we don't know. That's not how it works right now, but I think that's how it should work.

I have a different view.

Users don't care about libc or what hashes it supports. (Many PHP users probably don't even know what libc is.) Users definitely do not want their programs to fail when moved from a dev machine to a server, or from one server to another, because a different version of glibc is installed there.

It is better not to create unnecessary dependencies on the underlying system libraries. We need to use system APIs to access the hardware or modify the system state. But where just pure computation is involved, it almost never makes sense to rely on them.

If glibc supports some hashes which PHP doesn't know about, I would be happy to implement them.

We already have a high-level portable API for password hashing, which is the password_hash_* family of functions. You shouldn't be messing with tricky crypt() API if a portable password hash is all you want.

Using crypt() nowadays only ever makes sense if you specifically need to interoperate with crypt() based systems, e.g. if you want to process passwd files from PHP. For such use-cases, the only thing you care about is that crypt() in PHP behaves consistently with other crypt() based APIs on the same system.

@alexdowad
Copy link
Contributor Author

Regarding the last commit, I think we should be supporting system crypt as the fallback implementation for all the hashes we don't know. That's not how it works right now, but I think that's how it should work.

I have a different view.
Users don't care about libc or what hashes it supports. (Many PHP users probably don't even know what libc is.) Users definitely do not want their programs to fail when moved from a dev machine to a server, or from one server to another, because a different version of glibc is installed there.
It is better not to create unnecessary dependencies on the underlying system libraries. We need to use system APIs to access the hardware or modify the system state. But where just pure computation is involved, it almost never makes sense to rely on them.
If glibc supports some hashes which PHP doesn't know about, I would be happy to implement them.

We already have a high-level portable API for password hashing, which is the password_hash_* family of functions. You shouldn't be messing with tricky crypt() API if a portable password hash is all you want.

Using crypt() nowadays only ever makes sense if you specifically need to interoperate with crypt() based systems, e.g. if you want to process passwd files from PHP. For such use-cases, the only thing you care about is that crypt() in PHP behaves consistently with other crypt() based APIs on the same system.

OK. Fair enough.

If that is so, it does call into question why we have the in-tree implementation of crypt_r and its various hashes. It sounds like it is basically just for people who are misusing the crypt() function.

@alexdowad
Copy link
Contributor Author

@nikic... So I guess I can close this PR?

Do you think the docs for crypt should be updated to reflect its intended use?

@nikic
Copy link
Member
nikic commented Jun 24, 2020

Just my 2c ;) Maybe, given that we have not been using system crypt for so long due to a configure bug, it makes more sense to drop support for it as proposed.

I wonder if @remicollet or @oerdnj patch PHP to use system crypt or not. (Distros commonly disable any custom implementations we have :)

@nikic nikic changed the title More simplification and cleanup of cryptographic hashing code Always use PHP's own crypt_r implementation, don't support system crypt Jun 24, 2020
@oerdnj
Copy link
Contributor
oerdnj commented Jun 25, 2020

Here's the commit from packaging repo:

commit ff02f63e0687d2325b89c51da883c5af005d1068
Author: Ondřej Surý <ondrej@sury.org>
Date:   Fri Nov 16 15:17:55 2012 +0100

    Return to PHP versions of crypt() functions, it's to big burden to carry on the patch

@alexdowad
Copy link
Contributor Author

Here's the commit from packaging repo:

commit ff02f63e0687d2325b89c51da883c5af005d1068
Author: Ondřej Surý <ondrej@sury.org>
Date:   Fri Nov 16 15:17:55 2012 +0100

    Return to PHP versions of crypt() functions, it's to big burden to carry on the patch

Thank you! Which repo is this?

@alexdowad alexdowad requested a review from bukka as a code owner October 7, 2023 13:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants