[php-src] Issue #20801: password_needs_rehash() returns true for security downgrades (lower cost/memory)

[email protected] (dg)
Newsgroups php.bugs
Message-ID <koBXVcTih7gCdC7YMK66hhPn5r3fYo0MR7TBrviEGQA@main.internal.php.net>
Issue: https://github.com/php/php-src/issues/20801
Author: dg

### Description

The `password_needs_rehash()` function returns `true` when the new options would **downgrade** security (e.g., lower cost for bcrypt, lower memory_cost for argon2), which can lead to unintentional weakening of password security.

## The following code:

```php
<?php
// Create a hash with high security (cost 12)
$hash = password_hash('test', PASSWORD_BCRYPT, ['cost' => 12]);
echo "Hash created with cost 12: " . substr($hash, 0, 7) . "...\n";

// Check if rehash is needed with LOWER cost (security downgrade)
$needsRehash = password_needs_rehash($hash, PASSWORD_BCRYPT, ['cost' => 5]);
echo "needsRehash (cost 12 -> 5): " . var_export($needsRehash, true) . "\n";

// This is dangerous - application might rehash to weaker security
if ($needsRehash) {
    $weakerHash = password_hash('test', PASSWORD_BCRYPT, ['cost' => 5]);
    echo "Password downgraded from cost 12 to cost 5!\n";
}
```

## Resulted in this output:

```
Hash created with cost 12: $2y$12$...
needsRehash (cost 12 -> 5): true
Password downgraded from cost 12 to cost 5!
```

## But I expected this output instead:

```
Hash created with cost 12: $2y$12$...
needsRehash (cost 12 -> 5): false
(no downgrade performed)
```

## Expected behavior

`password_needs_rehash()` should return `false` when the new options would **weaken** security compared to the existing hash. It should only return `true` for:
- Algorithm changes
- Security **upgrades** (higher cost, higher memory_cost, etc.)
- Missing/corrupted hashes

## Actual behavior

The function returns `true` for ANY difference in options, including downgrades, which can lead to:
1. Accidental security weakening during configuration changes
2. Rollback/deployment issues where old config downgrades all passwords
3. No protection against misconfiguration



### PHP Version

```plain
This affects all PHP versions and all password algorithms (bcrypt, argon2i, argon2id)
```

### Operating System

_No response_
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.