In what scenarios would bin2hex be vulnerable to a timing attack?
The timing attack discussed in the mailing list and blog post is a cache-timing attack, which was famously demonstrated by Daniel J. Bernstein against OpenSSL's implementation of AES here (PDF).
In order for bin2hex()
to be vulnerable to a timing attack, the following conditions must be met:
- Internally, it either indexes or branches based on the secret we are trying to protect (e.g. HMAC key). The PHP implementation does index based on what could potentially be a secret.
- The attacker has to be able to alter the state of the processor cache somehow. (e.g. Renting a neighbor VM on the same baremetal machine with your cloud provider and executing a strategy similar to FLUSH+RELOAD.)
- The attacker can rapidly issue many valid requests from a privileged network position with minimal network jitter (surprisingly trivial these days).
- The key we want to protect is reused. (General case; some CSRF tokens are not reused.)
The feasibility of such an attack is still an unknown, but patching this potential side-channel is actually not that difficult. The previously linked methods were derived from libsodium's bin2hex implementation, which was provided by CodesInChaos.
Is this below code for handling a CSRF token vulnerable to a timing attack?
I don't know. The bin2hex()
might be a very minor concern, but not one that I can demonstrate a practical exploit for. Maybe someone in Crypto Stack Exchange can?
Update: There's a Lib for That
If you use paragonie/constant_time_encoding (which didn't exist when you asked this question), you shouldn't leak any information via cache timing.
<?php
use \ParagonIE\ConstantTime\Hex;
$rawBinary = random_bytes(32);
$data = Hex::encode($rawBinary);
$decoded = Hex::decode($data);
This library cover all of the RFC 4648 encoding schemes:
- Hex
- Base32
- Base32Hex
- Base64
- Base64UrlSafe
- Base64DotSlash
- Base64DotSlashOrdered
The latter two are compatible with crypt(3)
.