-
Notifications
You must be signed in to change notification settings - Fork 0
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
Use Hash::needsRehash in HasAttributes::castAttributeAsHashedString instead of Hash::isHashed #1
Conversation
I was thinking that rather than using We'd need to duplicate the It feels like a lot of extra complexity, but I'm worried that if we don't support a range of hash configs, it will break stuff - as you've pointed out with the User Factory. Consider if the app changes it's rounds from 10 -> 12, any existing hashes being passed around and set on user models will get hashed again - it feels like a very strange use case, but not completely outside possibility. But this is only an issue if we're targeting 10.x - if we make it a breaking change and target 11.x, it can be documented and we're all good. So I think we either need to bump this to 11.x as a breaking change or add the complexity to handle it in a flexible way. |
@valorin I'm not sure to understand everything well
Something like class BcryptHasher extends AbstractHasher implements HasherContract
{
protected $defaultRounds = 12;
protected $rounds = 12;
public function __construct(array $options = [])
{
$this->rounds = $options['rounds'] ?? $this->rounds;
$this->defaultRounds = max($this->defaultRounds, $this->rounds);
...
}
// ...
} ?
I'm not comfortable with only targetting 11.x. This would mean let the security issue in 10.x forever. I will try to take a look on this tomorrow, between 2 client projects... |
cb97c35
to
e52fc3f
Compare
Here is my new attempt to solve the problem in a non-breaking way. I let @taylorotwell fix the naming, I know you will find a much better one than mine. About the implementation @valorin what's your point of view about this implementation ? |
Nice, that's basically was I was thinking! Good work solving the Argon question too. My only concern is that the values are hardcoded away from the class default - so they could potentially be missed and not updated, but that's probably years off. |
I don't think your concerns are not a real problem as this should be a temporary fix for Laravel 10 which will get security fixes only until February 2025. |
…laravel#49474) * test: validateJson should return false when value is null Fails with Laravel Framework 10.38.2 in PHP < 8.3, introduced in laravel#49413 * fix: validateJson should return false when value is null Return false when $value is null. Avoid TypeError: json_validate(): Argument #1 ($json) must be of type string, null given, when using symfony/polyfill-php83 in PHP < 8.3. Avoid deprecation warning: json_validate(): Passing null to parameter #1 ($json) of type string is deprecated, when using PHP 8.3. --------- Co-authored-by: Rogelio Jacinto <rogelio@elabmexico.com>
Implementation of
hashed
cast fix. The fix is based onHash::needsRehash
which will check if the hash was generated with the same configurations as the default hasher. (https://www.php.net/manual/en/function.password-needs-rehash.php)It will causes a breaking change, if the developer currently creates the User with
hashed
cast and modifying the configuration, for example :With this new implementation, the password will be hashed twice. The probability is, IMHO, quite low and the fix is quite easy as it only requires to drop the
hashed
cast. It should not be a problem as the developer already hashes the password by hand.Unfortunately, this implementation also requires changes in the laravel/laravel project.
Indeed, the
User
declareshasehd
cast andUserFactory
declaresTo speed up tests, in
phpunit.xml
, environment variableBCRYPT_ROUNDS
is overrided to4
.As model factories can be used in tests (rounds 4 by default) and seeders (rounds 12 by default), we cannot define a pre-hashed value because of a double hashing in tests.
Therefore, there only viable solution I can think of is to drop the pre-hashed value and define
This way, the hash will always be generated with the correct config and won't be double hashed.
Another solution would be to defined
and let the cast do its job.
It won't slow down too much the tests as the
BCRYPT_ROUNDS
is at its minimum.Unfortunately, this change needs to be made on every project using
hashed
cast on user's password (and the other models/attributes using the cast).@valorin You proposed to block if the rounds if more than X above the config value. I don't think it will fix that UserFactory issue because of the difference between the config in the pre-hashed value (12) and the config (4) during the tests.
I hope we could have a better idea to solve initial issue, at this time I don't...
@taylorotwell @valorin I wait for your reviews before targeting laravel/framework