Skip to content

Fix #13692: Openssl cipher method refinement is unsafe on PHP 8.4 and older due to a PHP bug#4972

Closed
phpstan-bot wants to merge 2 commits into2.1.xfrom
create-pull-request/patch-kxr82r2
Closed

Fix #13692: Openssl cipher method refinement is unsafe on PHP 8.4 and older due to a PHP bug#4972
phpstan-bot wants to merge 2 commits into2.1.xfrom
create-pull-request/patch-kxr82r2

Conversation

@phpstan-bot
Copy link
Collaborator

Summary

On PHP 8.0-8.4, openssl_get_cipher_methods() reports cipher algorithms that are not actually supported by OpenSSL functions like openssl_cipher_iv_length() and openssl_cipher_key_length(). This is due to a PHP bug (php/php-src#19994) where openssl_get_cipher_methods() uses a different source of algorithms than the actual cipher functions, causing it to list algorithms that OpenSSL 3.0 has disabled by default.

This caused PHPStan to incorrectly refine the return type of these functions — for example, openssl_cipher_iv_length('aes-128-cbc-cts') was narrowed to int when it actually returns false on PHP 8.0-8.4.

Changes

  • Added src/Type/Php/OpenSslCipherMethodsProvider.php — a shared service that filters the cipher methods list by actually testing each algorithm with openssl_cipher_iv_length(), excluding those that return false (i.e. are not truly supported)
  • Updated src/Type/Php/OpensslCipherFunctionsReturnTypeExtension.php to use the new shared provider instead of directly querying openssl_get_cipher_methods()
  • Updated src/Type/Php/OpenSslEncryptParameterOutTypeExtension.php to use the same shared provider for consistent behavior

Root cause

openssl_get_cipher_methods() on PHP 8.0-8.4 uses EVP_CIPHER_do_all_sorted() to enumerate algorithms, while functions like openssl_cipher_iv_length() use EVP_get_cipherbyname() to resolve them. With OpenSSL 3.0+, the former returns algorithms from all providers (including disabled ones), while the latter only returns algorithms from loaded providers. This discrepancy was fixed in PHP 8.5 via a refactoring of the OpenSSL implementation.

The fix filters the algorithm list at PHPStan's analysis time by calling openssl_cipher_iv_length() for each algorithm and removing those that fail, ensuring only truly supported algorithms are used for type refinement.

Test

Added tests/PHPStan/Analyser/nsrt/bug-13692.php — verifies that openssl_cipher_iv_length('aes-128-cbc-cts') is correctly refined to false (not int) on PHP 8.4, while aes-128-cbc still correctly refines to int.

Fixes phpstan/phpstan#13692

phpstan-bot and others added 2 commits February 17, 2026 03:24
- openssl_get_cipher_methods() reports algorithms not actually supported
  on PHP 8.0-8.4 due to php/php-src#19994, causing incorrect type
  refinement (e.g. aes-128-cbc-cts narrowed to int instead of false)
- Added OpenSslCipherMethodsProvider that filters cipher methods by
  testing each with openssl_cipher_iv_length() to exclude broken ones
- Updated OpensslCipherFunctionsReturnTypeExtension and
  OpenSslEncryptParameterOutTypeExtension to use the shared provider
- New regression test in tests/PHPStan/Analyser/nsrt/bug-13692.php

Closes phpstan/phpstan#13692
Automated fix attempt 1 for CI failures.
@VincentLanglet
Copy link
Contributor

Cherry-picked in #4982

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.

2 participants