web-dev-qa-db-fra.com

L'idée centrale derrière la protection CSRF est-elle que le pirate ne connaît pas la valeur du jeton?

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?

30
MeanGreen

Votre compréhension est correcte.

Contexte

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)

Biscuits

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.

Solutions

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:

  • quelque part sur la page HTML (peut-être dans un élément HTML caché),
  • ou dans un en-tête de réponse HTTP sans cookie,
  • ou s'il s'agit d'une API, vous pouvez la mettre dans un 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.


Références

24
Mike Ounsworth