J'essaie de bien comprendre le concept derrière CSRF, et plus important encore, comment se protéger contre cela.
Puis-je supposer, en utilisant uniquement CSRF, donc pas de XSS ou d'autres techniques, qu'un pirate ne peut pas connaître la valeur du jeton anti-CSRF aléatoire que j'insère dans la page?
Votre compréhension est correcte.
La façon la plus simple de penser à une attaque CSRF est que votre navigateur a deux onglets ouverts - Tab A: www.mybank.com
et onglet B: www.attacker.com
.
(Comme @Alex le fait remarquer dans les commentaires, plusieurs onglets ne sont pas nécessaires; l'important est que votre navigateur dispose de cookies d'authentification pour mybank.com
en mémoire. CSRF peut également se produire si vous étiez sur mybank.com
plus tôt, puis sans vous déconnecter, accédez à attacker.com
)
Historiquement, il était courant de stocker votre jeton d'authentification/session dans un cookie. C'est pratique pour les pages HTML pures (c'est-à-dire sans javascript) car lorsque vous envoyez une demande à www.mybank.com
, le navigateur attachera automatiquement tous les cookies d'authentification pertinents - aucune action requise de la part de votre page HTML afin de maintenir la session. CSRF est une attaque contre les jetons d'authentification basés sur les cookies: si l'onglet B (www.attacker.com
) envoie une demande à www.mybank.com
, le navigateur attachera automatiquement le cookie d'authentification, c'est-à-dire que l'onglet B peut envoyer des demandes comme s'il était connecté à l'onglet A.
Vous devez placer votre jeton d'authentification/session dans un endroit qui n'est pas un cookie. En se souvenant que l'onglet B ne peut voir aucun du contenu de l'onglet A, il y a un certain nombre d'endroits où vous pouvez mettre le jeton d'authentification/session:
token: ___
champ du corps JSON, etc.Peu importe où, tant que ce n'est pas dans un cookie.
Pour être complet, j'ajouterai que votre jeton anti-CSRF doit être suffisamment long et aléatoire pour empêcher l'attaquant de le deviner. Par exemple, si vous utilisez le même jeton anti-CSRF pour tous les utilisateurs, ou si vous le dérivez du nom d'utilisateur, alors peu importe que l'onglet B ne puisse pas lire le contenu de l'onglet A car ils peuvent deviner le jeton et l'inclure dans leur demande aveugle CSRF.