Sign the phar with SHA-1 instead of SHA-512 - #6632
SanderMuller wants to merge 1 commit into
Conversation
|
2 things come to mind
|
|
Thanks, both worth checking. The first one does not apply to this signature. You are right about the second one on x86. On security: the phar signature has no key. Anyone who can change On speed, I timed
On x86 runners that both report SHA-NI, PHP 8.5 hashes SHA-256 about four times faster than 8.3, which fits the hardware acceleration you mention. I did not test 8.4. On both arm64 runners (one is an Apple M1), SHA-256 is the slowest of the three, and slower than today's SHA-512. SHA-1 is faster than SHA-512 on every platform here. Against SHA-512, SHA-256 would save about 60-70 ms on x86 with PHP 8.5, and cost about 65-95 ms on arm64. I would keep SHA-1, but SHA-256 is a one-token change if you prefer it. |
Yes, since PHP 8.4: https://tideways.com/profiler/blog/whats-new-in-php-8-4-in-terms-of-performance-debugging-and-operations. This also applies to Phar signatures if I read the code correctly.
SHA-1 is only broken with regard to collisions, which are not applicable here. But if what Sander says is indeed true and it's just a hash check rather than an actual signature, then it's totally meaningless.
This is expected without SHA-NI, because SHA-256 uses 32 bit arithmetic, whereas SHA-512 uses 64 bit arithmetic. Either way, the correct solution for security is a Sigstore attestation, not a PGP signature and not a Phar signature. |
|
And FWIW: SHA-256 is only accelerated on x64. ARM also includes native instructions, but these are not included yet, because I'm unable to test correct functionality. The upstream library we used for SHA-NI also includes an ARM variant, so if anyone wants to add native SHA-256 for ARM for PHP 8.7 that should be easy enough to do. You would just need to test it. |
|
Thank you Tim for the insights.
@SanderMuller would be great you could try to work on such a php-src addition.
yes, we are aware that we need additional hardening for that |
PHP verifies the phar signature over the whole 31 MB file every time a process opens it, and a restarted run opens it twice. SHA-1 hashes it in about 30 ms, SHA-512 takes 50-80 ms. The signature only detects corruption, because phpstan.phar.asc is the authenticity check. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
a3f4048 to
3a373d6
Compare
|
@SanderMuller how is this |
|
Deciding SHA algorithm is a build time thing, but my question is rather whether this needs to be just in resign.php, or also somewhere in box.json settings for example too. Inspect the built artifacts (phar-file), whether they use the expected algorithm or not. |
|
I checked the artifacts of this PR's Compile PHAR run (36694375075).
The "Download base SHA PHAR" red here was a race. The job ran at 09:13, and the Compile PHAR run of the base (#6633's merge) finished at 09:19. Thanks @TimWolla, that explains the timings. On x86, 8.5 hashed SHA-256 in 32 ms against 125 ms on 8.3, and SHA-256 stayed the slowest on both arm64 runners. |
PHP checks the phar signature over the whole 31 MB file each time a process opens the phar. The turbo restart opens it a second time. With SHA-512 that check costs 50-80 ms per open, and SHA-1 costs about 30 ms. SHA-1 is the fastest algorithm phar supports; MD5 is slower in PHP's own hash code.
The signature has no key, so it only detects a corrupt file.
phpstan.phar.ascstays the authenticity check.phar.require_hash=0does not skip the check, so a user cannot turn it off.Phar::loadPhar()on the 2.3.x phar (a6c162e), median of 5:A one-file project with turbo and fork on, the same phar re-signed, wall median of 15 runs on GitHub runners (run):
--versionThe macOS runner is noisy; the ubuntu ranges are tight. The saving is a fixed amount per process. It matters for a test harness that runs PHPStan many times on small fixtures, and it is noise on a long analysis.
I ran the changed
resign.phpon the 2.3.x phar with a commit date. The result has a SHA-1 signature, every member keeps the commit date as its mtime,diagnoseshows turbo and fork, and analysis runs.🤖 Generated with Claude Code