Il contesto
Per un admin irrobustito, ho legato il token JWT a un'impronta del browser (fingerprint) per limitare il furto di token. A ogni richiesta, si riverifica l'impronta.
Il sintomo
Utenti disconnessi dopo pochi minuti, in modo casuale. Token però non scaduto.
La causa
Il fingerprint includeva componenti instabili:
// Mauvais : ces valeurs bougent
const fp = hash([
navigator.userAgent,
window.innerWidth + 'x' + window.innerHeight, // change au resize !
navigator.language,
]);
innerWidth/innerHeight cambia al minimo ridimensionamento → l'hash non corrisponde più → rifiuto.
La soluzione
Mantenere solo componenti stabili, e verificare con tolleranza:
const fp = hash([
navigator.userAgent,
navigator.language,
screen.width + 'x' + screen.height, // resolution ecran, pas la fenetre
navigator.platform,
]);
public function isFingerprintValid(array $tokenFp, array $requestFp): bool
{
foreach (['ua', 'platform'] as $key) {
if (($tokenFp[$key] ?? null) !== ($requestFp[$key] ?? null)) {
return false;
}
}
return true; // les composants secondaires ne bloquent pas
}
Cosa ne ricavo
- Un fingerprint = unicamente componenti stabili.
- Uguaglianza stretta su dati volatili = bug casuali garantiti.
- Il fingerprint completa, non sostituisce, le buone pratiche JWT.