symfony/symfony — pull request #12559 by ameliaikeda (2014-11-24 00:08:29+00:00)
Title: [Security] added a timing attack resistant string comparison that resists length leaking

| Q | A
| ------------- | ---
| Bug fix? | no
| New feature? | yes
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets |
| License | MIT
| Doc PR |

The current PHP implementation ([hash_equals](https://github.com/php/php-src/blob/PHP-5.6/ext/hash/hash.c#L734-L768), below) and the implementation in `StringUtils::equals` will leak length difference information:

```c
/* This is security sensitive code. Do not optimize this for speed. */
for (j = 0; j < Z_STRLEN_P(known_zval); j++) {
result |= known_str[j] ^ user_str[j];
}
```

This implementation gets around the issue by first hashing both inputs (known and user) with hmac-sha512 with a 128bit (16 byte) random key by default.

This is an optional, backwards compatible change that requires instantiating the StringUtils class with a `SecureRandomInterface` implementation to make use of. Previously, the constructor was private due to only static methods being available, but I do not believe this breaks backwards compatibility. `StringUtils::equals()` is still as-is. Coverage report is 100% for all methods added (tested in PHP 5.6).

Usage:

```php
$string = new StringUtils(new SecureRandom);
$known = "pebkac";
$user = "asbasdfasdf";

$equal = $string->equalsHash($known, $user);
```