strcmp vs. == vs. === in PHP for checking hash equality
When it comes to security I prefer to use the ===
operator. ===
ensures the two operands are exactly the same, without trying to accomodate some casting in order to "help" the comparison to reach a successful match - as it may help while developing thanks to a loose-typed language, like PHP.
Of course, one of the operand is to be trusted. A hash from the database is trustable, while the user input is not.
One can always dither for a while, coming to the conclusion there is no risk using ==
in a specific case. Maybe. But for instance
"0afd9f7b678fdefca" == 0 is true "aafd9f7b678fdefca" == 0 is also true
as PHP tries to convert the "hash" into a number (probably using atoi) which gives 0. While it is unlikely crypt
returns 0, I'd prefer to maximize the cases where the passwords don't match (and answer a support call) by using ===
, than allowing a rare case that I didn't think about by using ==
.
As for strcmp
, the function returns <0
or >0
if different, and 0 if equal. But
strcmp("3", 0003) returns 0 strcmp("0003", 0003) returns -3
which are not surprising after all. A literal 0003
is actually an integer, 3
and since strcmp expects a string, the 3
will be converted to "3"
. But that shows there is some conversion that may happen in this case, since strcmp is a function, while ===
is part of the language.
So my preference in that case goes to ===
(which is faster than ==
anyway).
You should be using the hash_equals() function that is built into PHP. There would be no need to make your own function. The hash_equals() will return a boolean value.
In my opinion it is usually NOT a good idea to use == or === for comparing strings let alone hashed strings.
That is incorrect, please look at the definition of the function.According to PHP:
Returns < 0 if str1 is less than str2;
> 0 if str1 is greater than str2,
and 0 if they are equal
It returns less than 0 if str1 is less than str2. Note the phrase "less than", it does not return just -1, but any negative value. The same happens when str1 is greater than str2, but it returns a positive, non-zero value. It returns a positive value that can be 1, or any number thereafter.
strcmp()
returns a number that is the difference between the two strings starting with the last character that was found to be similar.
Here is an example:
$output = strcmp("red", "blue");
The variable $output with contain a value of 16