Dans cette vidéo je vous propose de découvrir le principe des attaques temporelles et comment s'en protéger.
Principe
Le principe de cette attaque est d'obtenir des information sur un système en analysant le temps que le serveur met à exécuter certaines actions. Pour donner un exemple prenons ce code qui permet de gérer un système de connexion
const errorMessage = "Email ou mot de passe invalide"
function handleLogin ({ body }) => {
const user = db
.fetch("SELECT * FROM users WHERE email = ?", body.email)
if (
user === null ||
// Use hash algorithm to verify password (slow)
verifyPassword(body.password, user.password)
) {
return render('login', {
error: errorMessage
}))
}
return redirect('/account')
})
On met ici un message d'erreur volontairement évasif pour ne pas révéler si un email existe ou non dans notre base de données. Cependant, le temps de réponse est plus lent dans le cas où l'email existe (car on exécute la fonction de hachage qui est lente). Ainsi, en analysant le comportement de notre serveur un attaquant peut déterminer si un email existe ou non dans notre base de données en comparant le temps de réponse.
Se protéger
Pour se protéger contre ce type d'attaque, il faut faire en sorte qu'il n'y ai pas de différence significative dans le temps d'exécution suivant le chemin pris par notre code. Dans la situation vu précédemment on peut hasher le mot de passe dans le cas où on ne trouve pas d'utilisateurs.
const errorMessage = "Email ou mot de passe invalide"
function handleLogin ({ body }) => {
const user = db
.fetch("SELECT * FROM users WHERE email = ?", body.email)
if (
user === null ||
verifyPassword(body.password, user.password
) {
if (user === null) {
// Hash password to avoid timing attack
hashPassword(body.password, user.password)
}
return render('login', {
error: errorMessage
}))
}
return redirect('/account')
})