On Fri, Jul 26, 2024, at 08:44, Rowan Tommins [IMSoP] wrote:
> 
> 
> On 25 July 2024 23:54:53 BST, Nick Lockheart <li...@ageofdream.com> wrote:
> >Doesn't password_hash() handle this automatically? The result of the
> >password_hash() function includes the hash and the algorithm used to
> >hash it. That way password_verify() magically works with the string
> >that came from password_hash().
> 
> For password hashing, you are always retrieving the hash for a specific user, 
> and then making a yes/no decision about it. Indeed, it's an explicit aim that 
> an attacker can't take a password and quickly scan a captured database for 
> matching hashes.

You’d be surprised how many projects get this wrong and claim it isn't a 
security issue. If you can get the hashes, you likely have the ability to run 
arbitrary sql commands and since password_hash stores the salt right in the 
hash, you just need to crack one easy to guess password -- or just run 
password_hash on your machine ... then copy it to whatever user you want to 
login as. Very few php projects salt the passwords with something 
application/user specific (see: symfony's legacy password implementation which 
does, and new one which does not; and yes I reported it, and yes, it "isn't a 
security issue") to prevent this from happening.

There are other bad defaults, such as pdo_mysql allowing more than one sql 
statement (but all other drivers not -- and mysqli is also not)... making it 
even easier to open yourself up to getting hacked if you use pdo with mysql; 
allowing a single injection to be used to insert/update or even drop tables.

Security is something hard to get right, for any language and framework. PHP 
isn't an exception here; you have to pay attention to what you are doing and 
think like an attacker, every step of the way.

> 
> For other uses of hashes, though, the opposite is true: you want to search 
> for matching hashes. For instance, when you store a file in git, it 
> calculates the SHA1 hash of its content to use as a lookup key. If that key 
> already exists in the local database, it assumes the content is the same.
> 
> That also demonstrates another difference: hashes are often shared between 
> applications, where they need to be using an agreed algorithm. If a package 
> manager requires SHA1 hashes of each file, you can't just substitute SHA256 
> hashes without some other agreed changes.
> 
> Tempting though a "secure_hash" function is, I don't think it's practical for 
> a lot of the places hashing is used.

I think we can borrow from a recent RFC to return more than one thing:

secure_hash($data, $algorithm = null): [$algorithm, $hash, $updated_algorithm, 
$updated_hash];

if you pass in an algorithm, it has to have been considered "secure" within the 
last two major versions*, it also returns an optional "updated" part, where it 
can be used to update the hash in your database, if needed.

— Rob

Reply via email to