-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[Security] Use hash_equals when available for constant-time string comparison #11797
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
Conversation
👍 |
Note that |
ecd239e
to
74973e0
Compare
74973e0
to
38633f4
Compare
You're right @aforsblo. I've just updated the PR to use |
@dunglas I'm afraid that won't help. Now the strings will be compared by the interpreted implementation of the algorithm if the lengths differ, and by the presumably much faster native implementation if they are of the same length, thus potentially enabling an attacker to figure out the length of the secret string. |
I agree with @aforsblo, this is also warned in the description - "Compares two strings using the same time whether they're equal or not. A difference in length will leak" Ah this method is for comparing hashes of the same algorithm (thus same length). |
Closing as this is not appropriate. |
Maybe can we add a C implementation of the algorithm used in Symfony in php.net? |
@fabpot @aforsblo I've submitted a PR to php.net: #11802 (comment) / http://marc.info/?l=php-internals&m=140948282903040&w=2 From the comments in this PR, on the PHP internals list and on the Python issue tracker (http://bugs.python.org/issue15061) it seems that this is almost impossible to be sure that an advanced attacker cannot recover the length. Maybe should we add a warning about that in the PHPDoc of this implementation? |
It is impossible in the general case to prevent length information leakage. See this comment where I go into more detail. Symfony's current setup does indeed leak length information today. To understand why, let's talk about large strings. CPUs use caches to speed up and prevent needing to fetch from main memory (RAM). We can determine the length of our known string by watching the cache miss pattern. If the known string is 10 bytes, then by passing in a 100mb string, we know that known never cache misses due to the execution time (cache misses are quite expensive). So we are able to deduce length information even though the function is "timing safe". And that doesn't even approach the problem that it's PHP code that's executing, meaning that there are branches all over the place. Making things like So while the current The C implementation of So instead, I'd strongly recommend to always use the |
Thank you @ircmaxell for sharing your insights, you have convinced me that using @dunglas @fabpot I'm now in favor of merging the original version of this PR (without the length check), with the addition of a documentation warning about the length leakage. |
@aforsblo @fabpot I will reopen the PR when #11808 will be merged. The original PR doesn't work when arguments' types aren't strings (I propose casting them to string to avoid a BC break). As mentioned in php/php-src#792 (comment), HHVM tries hiding length information while PHP.net doesn't. I agree to update the PHPDoc of |
Well, my main issue is tries to hide is not hiding. So even HHVMs version will leak. It's just not as obvious, and much more subtle. But the leak is most definitely still there (and a savy attacker will be able to exploit it). |
…arison (again) (dunglas) This PR was merged into the 2.3 branch. Discussion ---------- [Security] Use hash_equals for constant-time string comparison (again) | Q | A | ------------- | --- | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | n/a | License | MIT | Doc PR | n/a Use the `hash_equals` function (introduced in PHP 5.6) for timing attack safe string comparison when available. Add in the DocBlock that length will leak (#11797 (comment)). Commits ------- 3071557 [Security] Add more tests for StringUtils::equals 03bd74b [Security] Use hash_equals for constant-time string comparison
…arison (again) (dunglas) This PR was merged into the 2.3 branch. Discussion ---------- [Security] Use hash_equals for constant-time string comparison (again) | Q | A | ------------- | --- | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | n/a | License | MIT | Doc PR | n/a Use the `hash_equals` function (introduced in PHP 5.6) for timing attack safe string comparison when available. Add in the DocBlock that length will leak (symfony/symfony#11797 (comment)). Commits ------- 3071557 [Security] Add more tests for StringUtils::equals 03bd74b [Security] Use hash_equals for constant-time string comparison
Use the
hash_equals
function (introduced in PHP 5.6) for timing attack safe string comparison when available.(#11795 reopened against the 2.3 branch.)