Click here to Skip to main content
15,867,594 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I'm implementing a CSRF protection system for my website (forms) and I've noticed a strange (?) thing using hash_equals + crypt. An example to explain it (PHP 8.1.8):

$sessionToken = crypt(“562710df09d5b3b1e33769cd50a7e15d0cad770e66771ebbe9”, ‘12345');


$postToken = crypt(“562710df09d5b3b1e33769cd50a7e15d0cad770e66771ebbe9”, ‘12345');
$res = hash_equals($sessionToken, $postToken);
var_export($res); // true (right)

$postToken = crypt(“562710df09d5b3b1e33769cd50a7e15d0cad770e66771ebbe8”, ‘12345'); // HERE I'VE CHANGED THE LAST CHARACTER (8 instead of 9)
$res = hash_equals($sessionToken, $postToken);
var_export($res); // true (while it should be false)

This doesn't happen if what you change is the first character of $postToken (it returns false), or if you don't use crypt in hash comparison (I've tried it).

Is it normal?

What I have tried:

$sessionToken = crypt(“562710df09d5b3b1e33769cd50a7e15d0cad770e66771ebbe9”, ‘12345');

$postToken = crypt(“562710df09d5b3b1e33769cd50a7e15d0cad770e66771ebbe9”, ‘12345');
$res = hash_equals($sessionToken, $postToken);
var_export($res); // true

$postToken = crypt(“562710df09d5b3b1e33769cd50a7e15d0cad770e66771ebbe8”, ‘12345');
$res = hash_equals($sessionToken, $postToken);
var_export($res); // true
Posted
Updated 21-Mar-23 4:54am
v3
Comments
Member 15627495 21-Mar-23 11:22am    
did you try with more 'errors' in the second $postToken ?

did you try with the basic :
 if( $sessionToken === $postToken ) {return true; }{ return false; } 


it reminds me about 'how work a 'binary compare' aside 'string compare' ... the 'string compare' return 'flexible' results. little differences are /escape/ in the result

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
Top Experts
Last 24hrsThis month


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900