J'ai un site Web où les gens peuvent voter comme ceci:
http://mysite.com/vote/25
Cela placera un vote sur le point 25. Je souhaite que ceci ne soit disponible que pour les utilisateurs enregistrés, et uniquement s'ils le souhaitent. Maintenant, je sais que quelqu'un est occupé sur le site Web et que quelqu'un leur donne un lien comme celui-ci:
http://mysite.com/vote/30
alors le vote sera une place pour lui sur le point sans qu'il le veuille.
J'ai lu l'explication sur le site Web de l'OWASP , mais je ne la comprends pas vraiment
Est-ce un exemple de CSRF et comment puis-je empêcher cela? La meilleure chose à laquelle je puisse penser consiste à ajouter quelque chose au lien, comme un hachage. Mais ce sera assez irritant de mettre quelque chose au bout de tous les liens. N'y a-t-il pas d'autre moyen de le faire?.
Une autre chose peut-être que quelqu'un peut me donner un autre exemple, parce que le site Web me semble assez fugue.
Cela pourrait devenir un exemple de CSRF si:
<img>
, par exemple) : faux
Par exemple, si je pouvais injecter cette balise <img>
dans le code source HTML de stackoverflow (et je peux le faire, car stackoverflow permet d’utiliser des balises <img>
dans ses publications) :
<img src="http://mysite.com/vote/30" />
Vous auriez juste voté pour cet article ;-)
La solution généralement utilisée consiste à placer dans l'URL un jeton dont la durée de vie est limitée dans le temps et à vérifier, lorsque l'URL est extraite, que ce jeton est toujours valide.
L'idée de base serait:
http://mysite.com/vote/30?token=AZERTYUHQNWGST
L'idée est la suivante:
Notez également que plus la session de l'utilisateur reste active une fois qu'il a quitté votre site, moins il y a de risques qu'elle soit toujours valide lorsqu'il visite le mauvais site.
Mais ici, il faut choisir entre sécurité et convivialité ...
Une autre idée (ce n’est pas parfaitement sûr, mais aider les gars ne sait pas forcer une demande POST) , serait d’accepter uniquement les demandes POST lorsque les gens le sont. vote:
Mais notez que ce n’est pas parfaitement sûr: c’est (probablement?) possible de forcer/forger une demande POST, avec un peu de Javascript.
Tout d’abord, la requête GET ne doit pas être utilisée pour modifier les états sur le serveur. Par conséquent, je recommanderais POST/PUT pour votre service de vote. Ceci est seulement une ligne directrice, mais un couperet.
Donc, à votre question, CSRF est un problème de client, donc peu importe le type de langue de serveur que vous utilisez (PHP dans votre cas). Le correctif standard est le même et va comme ceci: Avoir une valeur aléatoire dans l'URI/données POST et la même valeur dans l'en-tête Cookie. Si ces correspondances, vous pouvez être sûr qu'il n'y a pas de CSRF. Il y a beaucoup d'informations sur la façon dont cela pourrait être fait ici sur StackOverflow, par exemple. celui-là .
Bonne chance!
OWASP a un CSRFGuard pour PHP et ESAPI pour PHP que j'ai écrit il y a longtemps pour XMB -> UltimaBB -> GaiaBB.
Il semble que d'autres aient nettoyé ce code et permis des jetons plus forts:
https://www.owasp.org/index.php/PHP_CSRF_Guard
merci, Andrew
Il y a 3 joueurs dans une attaque CSRF
Les attaques CSRF dépendent de 2 faits
setcookie("sessionID", "0123456789ABCDEF", time()+3600);
)Si un attaquant pouvait par là ou par un autre, un utilisateur connecté demande ceci
// http://victim.website/vote/30
par exemple, en plaçant le lien sur le site Web de l'attaquant ou en l'envoyant par courrier électronique, le navigateur client connecté enverra les cookies d'identification (sessionID) avec cette demande, ce qui incitera le site Web de la victime à penser que son utilisateur connecté souhaite réellement voter!
Mais si le site Web de la victime est plus intelligent et vérifie les demandes de ses utilisateurs connectés avec un paramètre supplémentaire GET ou POST (pas les cookies), l'attaquant est maintenant dans un problème car les paramètres GET et POST ne sont pas envoyé automatiquement par les navigateurs, et il doit le deviner.
// http://victim.website/vote/30?csrfSecret=0123456789ABCDEF
L'attaquant ne connaît pas le paramètre csrfSecret
qui est un secret entre le site Web de la victime et son client (tout comme le jeton de session). Il n'a donc aucun moyen de créer l'URL par laquelle il souhaite forger une requête.
De même, si le vote est effectué à la demande de POST], l'attaquant ne pourra pas créer le formulaire sur son site Web (ou sur un site Web tiers) car il ne connaît pas le secret entre le site Web de la victime et ses utilisateurs.
<form method="post" action="http://victim.website/vote" >
<input type="hidden" name="vote" value="30">
<input type="hidden" name="csrfSecret" value="????? I don't know it :(">
</form>