2010-03-07 1 views
16

Je suis probablement un noob total ici, mais je ne suis toujours pas certain de ce qu'une attaque CSRF (Cross-Site Request Forgery) est exactement. Alors regardons trois situations ...Est-ce que je risque d'être victime d'attaques CSRF dans un formulaire POST qui ne nécessite pas que l'utilisateur soit connecté?

1) J'ai un formulaire POST que j'utilise pour éditer des données sur mon site. Je veux que ces données soient éditées seulement par les utilisateurs qui sont connectés.

2) J'ai un site, qui peut être utilisé par les utilisateurs qui sont connectés ainsi que les invités. Certaines parties du site sont réservées aux utilisateurs connectés, mais il existe également des formulaires POST pouvant être utilisés par tous les utilisateurs - anonymes et non (par exemple, un formulaire de contact standard). Le formulaire de contact devrait-il être protégé contre les attaques CSRF? 3) J'ai un site qui ne possède pas de système d'authentification (enfin, c'est peut-être irréaliste, alors disons qu'il a un site admin qui est séparé du reste et que la partie admin est correctement sauvegardée). La partie principale du site est uniquement utilisée par des utilisateurs anonymes. Les formulaires POST doivent-ils être protégés?

Dans le cas de 1), la réponse est clairement oui. Mais dans le cas de 2 et 3 je ne sais pas (et la différence entre 2 et 3 est-elle même significative?).

Répondre

32

Il y a des moyens de CSRF chaque fois que HTML ou JavaScript malveillant qui cible sur votre site Web est été intégrés dans une autre page HTML (ou un message électronique) qui est été exécutée avec succès.

Un exemple est le suivant qui est été placé dans une autre page Web qui demande innocemment votre nom et votre âge avant de poursuivre:

<form action="http://yoursite.com/transferfunds" method="post"> 
    Your name: <input type="text"><br> 
    Your age: <input type="text"><br> 
    <input type="submit"> 
    <input type="hidden" name="amount" value="1000"> 
    <input type="hidden" name="toaccount" value="12345678"> 
</form> 

Notez que les points d'action à votre site Web et que les entrées cachées contient le nécessaire POST informations. Cet exemple va essayer de transférer un fonds de 1000 (dans n'importe quelle devise) au numéro de compte 12345678. Si vous avez besoin d'un login sur votre formulaire et vérifie cela, alors ce qui précède ne sera bien sûr exécuté que si l'utilisateur inconscient récemment connecté à votre site Web, mais pas encore déconnecté, ou la session n'a pas encore expiré. Pour éviter cela, il est préférable d'ajouter un jeton basé sur une requête au formulaire et de le valider côté serveur. C'est à dire. générer une chaîne aléatoire longue, unique et impossible à deviner que vous stockez dans la session et l'incorporez comme élément <input type="hidden"> du formulaire. Lorsque le formulaire est soumis, comparez la valeur de jeton soumise avec celle déjà en session (et supprimez immédiatement celle en session). Pour aller plus loin, utilisez un CAPTCHA.

Dans votre cas particulier, je pense que vous êtes en fait plus préoccupé par XSS, ce qui est un contraire de CSRF, mais qui peut également être une source de CSRF. Un exemple de XSS est lorsque l'utilisateur entre ce qui suit dans un champ d'entrée qui va être réaffichée tôt ou tard sur le même site:

<form name="delete" action="admin/deleteusers" method="post"></form> 
<script>document.form.delete.submit();</script> 

Chaque fois que vous -AS être l'affiche la page administrateur-avec le commentaire avec la forme (invisible!) et le script à l'intérieur, alors il sera exécuté avec succès.

Prévenir XSS est en fait assez facile. Juste HTML-échapper toute entrée contrôlée par l'utilisateur (c'est-à-dire demande URL, en-têtes de demande, paramètres de demande et le corps de la demande) avant de les afficher sur la page Web.En PHP, vous pouvez utiliser htmlspecialchars() pour cela et en Java/JSP le JSTL fn:escapeXml(). De cette façon sous chacun des < sera converti en &lt; et > en &gt; ce qui fera que tout HTML/JS entré sera affiché tel quel et ne peut donc pas être exécuté.

+0

Merci - très utile :) (Même si je n'avais pas spécifiquement demandé, j'ai trouvé la comparaison à XSS très utile :)) Si je comprends bien alors je pourrais toujours vouloir utiliser CSRF dans quelque chose comme un formulaire de contact dans la prévention spambot, non? –

+1

Un jeton basé sur une requête et/ou un captcha est la meilleure approche. On ne sait pas quel est le langage de programmation de votre webapp. J'ai vérifié l'historique de vos questions et je suppose que vous ciblez Python. Vous pouvez alors trouver http://captchas.net utile. Le site contient un exemple Python. – BalusC

+0

Merci, bonnes réponses :) Je pense que je sais plus ou moins comment l'implémenter dans ma technologie de prédilection (le framework Django). Était juste pas clair sur la nature de l'attaque elle-même. –

Questions connexes