note 125034 added to function.hash-equals
| From: | examplehash.user.com via php-notes | Date: | Thu, 21 May 2020 19:19:04 +0000 |
| Subject: | note 125034 added to function.hash-equals | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-214662@lists.php.net to get a copy of this message | ||
None of the polyfills for this function to date are actually correct. A timing attack defensive
string comparison function must not take *any* shortcuts. If the function performs a single if-then
statement other than validating input types (i.e. making sure inputs are strings), then it is doing
the comparison incorrectly. But I'd argue that by the time you call the function, your inputs
should have already been sanitized. The top-most voted item by asphp incorrectly shortcuts on a
comparison of strlen() (enabling a precision oracle attack on string length), while Markus shortcuts
on knownstring (enabling an oracle attack on length of knownstring), and others shortcut in similar
ways.
Here is a correct implementation in PHP adapted from a correct C implementation:
function CTstrcmp($secret, $userinput)
{
$sx = 0;
$sy = strlen($secret);
$uy = strlen($userinput);
$result = $sy - $uy;
for ($ux = 0; $ux < $uy; $ux++)
{
$result |= ord($userinput[$ux]) ^ ord($secret[$sx]);
$sx = ($sx + 1) % $sy;
}
return $result;
}
Here, every byte of userinput is executed over regardless of the length of either string. An oracle
length attack is not possible since there is no comparison of lengths - just assignment and math.
The amount of time spent in the function is entirely dependent upon the length of userinput and can
only be correct (i.e. return 0) if userinput exactly matches the secret. Please take your time to
understand the key differences between this function and the others.
If you are porting the above to another language, be aware of how strings and whatever strlen()
equivalent works behind the scenes in your language. PHP stores the size of the data separately so
it can strlen() in O(1) time.
----
Server IP: 45.112.84.4
Probable Submitter: 103.51.166.36 (proxied: 159.54.136.10)
----
Manual Page -- http://php.net/manual/en/function.hash-equals.php
Edit -- https://master.php.net/note/edit/125034
Del: integrated -- https://master.php.net/note/delete/125034/integrated
Del: useless -- https://master.php.net/note/delete/125034/useless
Del: bad code -- https://master.php.net/note/delete/125034/bad+code
Del: spam -- https://master.php.net/note/delete/125034/spam
Del: non-english -- https://master.php.net/note/delete/125034/non-english
Del: in docs -- https://master.php.net/note/delete/125034/in+docs
Del: other reasons-- https://master.php.net/note/delete/125034
Reject -- https://master.php.net/note/reject/125034
Search -- https://master.php.net/manage/user-notes.php