2010-02-12 7 views
10

Pour protéger contre CSRF, vous devez placer un nonce dans un champ masqué dans le formulaire et dans un cookie ou dans la variable de session. Mais que faire si l'utilisateur ouvre plusieurs pages dans différents onglets? Dans ce cas, chaque onglet aurait un formulaire avec un nonce unique, mais il n'y aurait qu'un seul nonce stocké dans la variable de session ou cookie. Ou si vous essayez de stocker tous les nonces dans la variable cookie/session, comment identifieriez-vous celui qui appartient à quel formulaire?Protection CSRF en stockant le nonce dans la variable de session et le formulaire

Répondre

6

Vous pouvez stocker le même nonce dans chacun des formulaires. Le moyen le plus simple de le faire est de lier le nonce à l'identifiant de session, afin que ces formulaires ne fonctionnent que dans cette session.

Vous voudrez empêcher les attaquants de saisir les identifiants de session et de créer leurs propres fichiers. Donc, une façon d'y arriver est d'utiliser HMAC-SHA256 (ou similaire) pour hacher l'ID de session, en utilisant une clé que vous n'exposez pas au public.

(De toute évidence, si l'attaquant peut obtenir l'ID de session lui-même, il peut déjà effectuer un détournement de session.) Ce n'est pas de ça que je parle mais de la capacité d'un attaquant à créer un script. l'ordinateur de la victime) qui peut en quelque sorte saisir l'ID de session et l'utiliser pour générer dynamiquement une URL avec le nonce pré-remplies)


ETA. que ce soit l'approche ci-dessus est suffisante à elle seule dépend de combien de temps vous attendez vos sessions typiques pour durer. Si les utilisateurs utilisent généralement des sessions de longue durée qui durent plus de quelques heures, vous devrez utiliser quelque chose de plus sophistiqué.

Une approche est de créer un nouveau nonce pour chaque forme, qui contient l'horodatage, ainsi que hash(timestamp . sessionid) (où hash est une variante de HMAC comme décrit ci-dessus, pour empêcher la falsification, et . est la concaténation de chaîne). Vous vérifiez le nonce par:

  1. vérification de l'horodatage pour faire en sorte que le nonce est assez frais (ce qui est à votre politique, mais quelques heures est typique)
  2. puis, le calcul du hachage sur la base horodatage et ID de session, et comparaison avec le nonce, pour vérifier que le nonce est authentique

Si la vérification de nonce échoue, vous devrez afficher un nouveau formulaire, pré-rempli avec la soumission de l'utilisateur (de sorte que si ils ont pris une journée entière pour écrire leur poste, ils ne perdront pas tout leur dur labeur), ainsi qu'un nouvel emploi. Ensuite, l'utilisateur peut resoumettre tout de suite avec succès.

+0

Donc, vous ne générez pas un nouveau nonce à chaque fois alors? Le nonce resterait le même pendant toute la session, et pour plusieurs soumissions. – Marius

+0

@Marius: Je mettrai à jour ma réponse pour répondre à votre commentaire. :-) –

+0

-1 Non, l'attaquant n'a pas l'identifiant de session, le navigateur le fait. Ce n'est pas un travail pour un HMAC. – rook

2

Certaines personnes génèrent un jeton pour chaque formulaire, ce qui constitue une approche très sécurisée. Cependant, cela peut casser votre application et énerver les utilisateurs. Pour empêcher toute XSRF contre votre site, vous avez juste besoin d'une seule variable jeton par session, et l'attaquant ne pourra forger aucune requête à moins qu'il ne puisse trouver ce jeton. Le problème mineur lié à cette approche est que l'attaquant peut forcer la force brute de ce jeton tant que la victime visite un site Web contrôlé par l'attaquant. Cependant, si le jeton est assez gros comme 32 octets ou plus, il faudra de nombreuses années à la force brute, et la session http devrait expirer bien avant.

+0

L'attaquant ne peut-il pas simplement demander au formulaire d'obtenir un jeton valide? Cela semble assez simple. –

+1

@Chris Moschini ce n'est pas comment fonctionne xsrf. Vous participez à la séance de quelqu'un d'autre que la vôtre, cela n'a tout simplement aucun sens. – rook

+0

Merci. Qu'en est-il lorsque le serveur est derrière un proxy inverse et que la session HTTP est renouvelée pour chaque requête? –

0

Il ya longtemps que ce post a été écrit. J'ai implémenté un bloqueur csrf que je suis presque certain de bien protéger. Il fonctionne avec plusieurs fenêtres ouvertes, mais j'évalue toujours le type de protection qu'il offre. Il utilise une approche DB, c'est-à-dire stocker à la place d'une session dans une table. NOTE: J'utilise MD5 dans ce cas comme un mécanisme anti-sqli facile

Pseudo Code:

FORMULAIRE:

token = randomstring #to be used in form hidden input 
db->insert into csrf (token, user_id) values (md5(token),md5(cookie(user_id)) 

- le jeton est alors maintenu dans la db jusqu'à ce qu'il est accessible à partir de le script d'action, ci-dessous:

ACTION sCRIPT:

if md5(post(token)) belongs to md5(cookie(user_id)) 
    #discard the token 
    db -> delete from csrf where token=md5(post(token)) and user_id=md5(cookie(user_id)) 
    do the rest of the stuff 
+0

L'ajout de l'ID utilisateur à l'enregistrement n'ajoute pas réellement à la sécurité, mais il permet de supprimer les jetons inutilisés de l'utilisateur de la base de données lors de la déconnexion. –

2

Ce que vous décrivez n'est plus un nonce (nonce = numéro utilisé une fois), c'est juste un identifiant de session. Le but d'un nonce est qu'il n'est valable que pour une seule soumission de formulaire, donc offre une plus grande sécurité contre le piratage qu'un simple ID de session, mais au prix de ne pas avoir plusieurs onglets fonctionnant en parallèle sur le site.

Les nonces sont exagérées à de nombreuses fins. Si vous les utilisez, vous ne devez les définir et les exiger que sur des formulaires qui apportent des modifications critiques au système, et informer les utilisateurs qu'ils ne peuvent pas utiliser plus d'un tel formulaire en parallèle. Les pages qui ne définissent pas de nonce doivent veiller à ne effacer aucun descripteurs précédemment stockés dans la session, afin que les utilisateurs puissent toujours utiliser des pages non-non-cuites en parallèle avec un formulaire non-signé.