diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-09-07 15:43:26 +0200 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-09-07 15:43:26 +0200 |
commit | 032f862133dbd2acc04cb75004428d6209f6046b (patch) | |
tree | c56bc8b35d7a82bbdeece6986750a3aefdbe1f57 | |
parent | f4b2497ad8c366d276689dd1c7e3a84c33c11d9b (diff) | |
download | php-git-032f862133dbd2acc04cb75004428d6209f6046b.tar.gz |
Drop support for crypt() without explicit salt
crypt() without salt generates a weak $1$ MD5 hash. It has been
throwing a notice since 2013 and we provide a much better alternative
in password_hash() (which can auto-generate salts for strong
password hashes), so keeping this is just a liability.
-rw-r--r-- | UPGRADING | 3 | ||||
-rwxr-xr-x | ext/standard/basic_functions.stub.php | 2 | ||||
-rwxr-xr-x | ext/standard/basic_functions_arginfo.h | 4 | ||||
-rw-r--r-- | ext/standard/crypt.c | 33 | ||||
-rw-r--r-- | ext/standard/tests/strings/crypt.phpt | 12 |
5 files changed, 16 insertions, 38 deletions
@@ -576,6 +576,9 @@ PHP 8.0 UPGRADE NOTES $ctx = stream_context_create(['http' => ['protocol_version' => '1.0']]); echo file_get_contents('http://example.org', false, $ctx); + . Calling crypt() without an explicit salt is no longer supported. If you + would like to produce a strong hash with an auto-generated salt, use + password_hash() instead. - Sysvmsg: . msg_get_queue() will now return an SysvMessageQueue object rather than a diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php index 75819c7fb5..44eb05a015 100755 --- a/ext/standard/basic_functions.stub.php +++ b/ext/standard/basic_functions.stub.php @@ -391,7 +391,7 @@ function crc32(string $str): int {} /* crypt.c */ -function crypt(string $str, string $salt = UNKNOWN): string {} +function crypt(string $str, string $salt): string {} /* datetime.c */ diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h index 9d13b25b85..ef031e7afb 100755 --- a/ext/standard/basic_functions_arginfo.h +++ b/ext/standard/basic_functions_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 010a6e0dee6d5e419e66eeefadd4dfabbbddfaca */ + * Stub hash: 28da5d6df91403aad82b5872453053dc41076a6a */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0) ZEND_ARG_TYPE_INFO(0, seconds, IS_LONG, 0) @@ -597,7 +597,7 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_crc32, 0, 1, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_crypt, 0, 1, IS_STRING, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_crypt, 0, 2, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, str, IS_STRING, 0) ZEND_ARG_TYPE_INFO(0, salt, IS_STRING, 0) ZEND_END_ARG_INFO() diff --git a/ext/standard/crypt.c b/ext/standard/crypt.c index f994ff4c31..8c105cf910 100644 --- a/ext/standard/crypt.c +++ b/ext/standard/crypt.c @@ -79,18 +79,6 @@ PHP_MSHUTDOWN_FUNCTION(crypt) /* {{{ */ } /* }}} */ -static unsigned char itoa64[] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; - -/* Encode a string of bytes as Base64 */ -static void php_to64(char *s, int n) /* {{{ */ -{ - while (--n >= 0) { - *s = itoa64[*s & 0x3f]; - s++; - } -} -/* }}} */ - PHPAPI zend_string *php_crypt(const char *password, const int pass_len, const char *salt, int salt_len, zend_bool quiet) { char *crypt_res; @@ -216,9 +204,8 @@ PHP_FUNCTION(crypt) size_t str_len, salt_in_len = 0; zend_string *result; - ZEND_PARSE_PARAMETERS_START(1, 2) + ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_STRING(str, str_len) - Z_PARAM_OPTIONAL Z_PARAM_STRING(salt_in, salt_in_len) ZEND_PARSE_PARAMETERS_END(); @@ -227,23 +214,9 @@ PHP_FUNCTION(crypt) /* This will produce suitable results if people depend on DES-encryption * available (passing always 2-character salt). At least for glibc6.1 */ memset(&salt[1], '$', PHP_MAX_SALT_LEN - 1); + memcpy(salt, salt_in, MIN(PHP_MAX_SALT_LEN, salt_in_len)); - if (salt_in) { - memcpy(salt, salt_in, MIN(PHP_MAX_SALT_LEN, salt_in_len)); - } else { - php_error_docref(NULL, E_NOTICE, "No salt parameter was specified. You must use a randomly generated salt and a strong hash function to produce a secure hash."); - } - - /* The automatic salt generation covers standard DES, md5-crypt and Blowfish (simple) */ - if (!*salt) { - memcpy(salt, "$1$", 3); - php_random_bytes_throw(&salt[3], 8); - php_to64(&salt[3], 8); - strncpy(&salt[11], "$", PHP_MAX_SALT_LEN - 11); - salt_in_len = strlen(salt); - } else { - salt_in_len = MIN(PHP_MAX_SALT_LEN, salt_in_len); - } + salt_in_len = MIN(PHP_MAX_SALT_LEN, salt_in_len); salt[salt_in_len] = '\0'; if ((result = php_crypt(str, (int)str_len, salt, (int)salt_in_len, 0)) == NULL) { diff --git a/ext/standard/tests/strings/crypt.phpt b/ext/standard/tests/strings/crypt.phpt index 270f0372d1..462aea8b59 100644 --- a/ext/standard/tests/strings/crypt.phpt +++ b/ext/standard/tests/strings/crypt.phpt @@ -18,14 +18,16 @@ echo (CRYPT_EXT_DES) ? ((crypt($str, $salt2) === $res_2) ? 'EXT' : 'EXT - ERROR echo (CRYPT_MD5) ? ((crypt($str, $salt3) === $res_3) ? 'MD5' : 'MD5 - ERROR') : 'MD5', "\n"; echo (CRYPT_BLOWFISH) ? ((crypt($str, $salt4) === $res_4) ? 'BLO' : 'BLO - ERROR') : 'BLO', "\n"; -var_dump(crypt($str)); +try { + var_dump(crypt($str)); +} catch (ArgumentCountError $e) { + echo $e->getMessage(), "\n"; +} ?> ---EXPECTF-- +--EXPECT-- STD EXT MD5 BLO - -Notice: crypt(): No salt parameter was specified. You must use a randomly generated salt and a strong hash function to produce a secure hash. in %s on line %d -string(%d) "%s" +crypt() expects exactly 2 parameters, 1 given |