Protection contre les failles CSRF

ViPHP
xTG
ViPHP | 7331 Messages

16 janv. 2011, 14:08

Bonjour à toutes et à tous,

j'ai décidé d'apprendre un peu plus sur la sécurité des sites internet, côté qui m'avait pas mal manqué jusque là (oubli de m'informer, pas le temps, la flemme, [....], fin liste exhaustive).

Je me suis donc potassé quelques articles et sites mais je rencontre des difficultés à mettre en place une sécurité contre ce type de faille.
J'ai pleinement compris qu'il fallait utiliser un jeton et vérifier que c'était le même que celui généré par le formulaire de connexion.
Cependant... Je fais comment après un changement de page ?

Ma fonction de vérification vérifie le jeton avec le jeton envoyé par le formulaire (en champs hidden).
Mais bien évidement si je change de page après cette vérification la fonction me renvoie false puisque je ne viens plus du formulaire...
Je n'ai pas trouvé d'informations explicites me permettant de régler mon problème, tous les articles et exemples que j'ai pu lire se cantonnent à une page formulaire et une page verif...

Un coup de pouce ou de pied pour moi ?

Modérateur PHPfrance
Modérateur PHPfrance | 2575 Messages

16 janv. 2011, 15:02

Bonjour xTG,

Justement la sécurité contre les injections se limite aux mécanismes interactifs client/serveur où le serveur doit faire confiance au client et vis-versa quant à un échange de données entre le client et le serveur. Si un scénario de communication client/serveur exige un échange de données sensibles plus ou moins durable, la communication exige alors un canal sécurisé de type SSL où la confiance est gérée par un système de gestion de certificats d'identification. Le système de jeton que tu décris se limiter à une sorte de SID stocké dans un champ hidden n'est pas très sûr dans le temps et exige donc un taux de rotation de codification élevé (c'est à dire un jeton jetable qui n'est valable qu'une fois pour une seule communication asynchrone : le client demande un jeton, le reçoit, envoi ses données et le serveur valide ensuite le serveur "oubli" le client)
--------//////----//---//----//////
-------//---//----//---//----//---//
------//////----//////-----//////
-----||--------||--||---||
Prendre le recul n'est pas une perte de temps.


ps: Affrontez moi dans l'arène

Mammouth du PHP | 1511 Messages

16 janv. 2011, 15:05

La vérification du jeton ne s'effectue que lors de la soumission dudit formulaire, afin de vérifier de la validité de celui-ci.

Quelle utilité de vérifier le jeton sur une autre page ?

ViPHP
xTG
ViPHP | 7331 Messages

16 janv. 2011, 15:13

Okay je comprend mieux, et surtout que ce système de jeton m'est totalement inutile...
En gros il est utile si l'utilisateur doit remplir un formulaire l'identifiant avant chaque action ou bien pour vérifier la provenance des données, mais dans le cas d'une session durable ce n'est pas applicable.

Pour mon identification je vais donc abandonner les jetons, cependant je vais tenter de l'adapter pour la soumission des formulaires en page admin. :)

Sinon pour le SSL j'y avais pensé mais mon hébergement ne me le permet pas, donc je recherche des solutions à la mano. ^^

devlop78
Invité n'ayant pas de compte PHPfrance

18 janv. 2011, 12:47

Bonjour à toutes et à tous,

j'ai décidé d'apprendre un peu plus sur la sécurité des sites internet, côté qui m'avait pas mal manqué jusque là (oubli de m'informer, pas le temps, la flemme, [....], fin liste exhaustive).

Je me suis donc potassé quelques articles et sites mais je rencontre des difficultés à mettre en place une sécurité contre ce type de faille.
J'ai pleinement compris qu'il fallait utiliser un jeton et vérifier que c'était le même que celui généré par le formulaire de connexion.
Cependant... Je fais comment après un changement de page ?

Ma fonction de vérification vérifie le jeton avec le jeton envoyé par le formulaire (en champs hidden).
Mais bien évidement si je change de page après cette vérification la fonction me renvoie false puisque je ne viens plus du formulaire...
Je n'ai pas trouvé d'informations explicites me permettant de régler mon problème, tous les articles et exemples que j'ai pu lire se cantonnent à une page formulaire et une page verif...

Un coup de pouce ou de pied pour moi ?
Si tu regardes les appli les plus courantes, comme PhpMyAdmin, leur token est unique par session. Cela veut dire qu'il n'est généré qu'avec une nouvelle session. Cela permet d'éviter une destruction du jeton si on ouvre plusieurs fenetres, et ensuite, si l'attaque se fait par email ou un site externe, il n'est à priori pas capable d'avoir accès à ton jeton, donc cela convient. A+

PS : Moi j'ai prévu de lire "Developpement web : Généralités sur la sécurité" par Julien Pauli, et "Sécurité de PHP et MySQL" (qui est beaucoup plus conséquent en volume et à l'air très complet).

ViPHP
xTG
ViPHP | 7331 Messages

18 janv. 2011, 14:13

Hum et si la personne a quitté le site sans se déconnecter ?
La session est de nouveau active à l'ouverture du site(via le mail).
C'est surtout ce genre de faille qui pose problème.
Car le fait de générer des valeurs aléatoire pour chaque session ne pose pas gros problème.

devlop78
Invité n'ayant pas de compte PHPfrance

19 janv. 2011, 01:36

Hum et si la personne a quitté le site sans se déconnecter ?
La session est de nouveau active à l'ouverture du site(via le mail).
C'est surtout ce genre de faille qui pose problème.
Car le fait de générer des valeurs aléatoire pour chaque session ne pose pas gros problème.
Oui, mais que peut-il faire sans token ...

Mammouth du PHP | 1511 Messages

19 janv. 2011, 04:15

Dans le cas d'une ouverture par lien dans un mail, la vérification du referer + du timestamp de la dernière visite pourrait s'avérer un choix judicieux isn't it ?

ViPHP
xTG
ViPHP | 7331 Messages

19 janv. 2011, 10:01

Hum et si la personne a quitté le site sans se déconnecter ?
La session est de nouveau active à l'ouverture du site(via le mail).
C'est surtout ce genre de faille qui pose problème.
Car le fait de générer des valeurs aléatoire pour chaque session ne pose pas gros problème.
Oui, mais que peut-il faire sans token ...
Bah si le token est en corrélation avec la session il l'a le token ?_?

Le coup du referer j'aime pas trop car c'est modifiable...
Par contre le timestamp pour l'inactivité j'aime bien ! Je vais rajouter cela à mon système de session.

devlop78
Invité n'ayant pas de compte PHPfrance

19 janv. 2011, 21:47

Hum et si la personne a quitté le site sans se déconnecter ?
La session est de nouveau active à l'ouverture du site(via le mail).
C'est surtout ce genre de faille qui pose problème.
Car le fait de générer des valeurs aléatoire pour chaque session ne pose pas gros problème.
Oui, mais que peut-il faire sans token ...
Bah si le token est en corrélation avec la session il l'a le token ?_?

Le coup du referer j'aime pas trop car c'est modifiable...
Par contre le timestamp pour l'inactivité j'aime bien ! Je vais rajouter cela à mon système de session.
Non, ou alors on parle du XSS ... Pour le CSRF, le "méchant" n'a même pas conscience du n° de session, il utilise juste le fait que le gentil soit connecté. Le problème, c'est que le gentil va sur delete.php qui génère (on va prendre le cas du GET), des liens de type delete.php?id=5 mais avec un token donc delete.php?id=5&token=C589DE44DDEE44, token qui va changer à chaque page, ou qui dure toute la session (ici dans mon exemple ça ne change rien). Si le méchant envoie un email au gentil avec une image src="gentil.com/admin/delete.php?id=5", il ne passera rien puisque le token, il ne l'a pas. Pour l'avoir, il faudrait qu'il utilise des techniques telles qu'il aura de fortes chances d'avoir aussi le numéro de session avec ... donc de toutes façons ... Par contre en limitant le temps d'inactivité, et en enregistrant le nom du navigateur, des infos par ci par là (qu'on dit alors devenir unique, comme la prise en charge de Flash etc), le site peut comparer ça à chaque fois, et deconnecter d'urgence si il y a la moindre incompatibilité. Or, un navigateur ne change pas de nom lors d'une même session, et ne change pas trop de configuration non plus. Et au pire, il s'agit de la sécurité, devoir se reconnecter, c'est pas grand chose. C'est d'ailleurs tout aussi primordial pour les grandes opérations.

ViPHP
xTG
ViPHP | 7331 Messages

20 janv. 2011, 07:32

D'accord, du coup tu m'as éclairé sur le fait qu'il vaut mieux que je passe le token en GET sur toutes les pages (plus simple que du $_POST).
Merci de ces explications. :)

devlop78
Invité n'ayant pas de compte PHPfrance

21 janv. 2011, 01:48

Oui par contre un token dynamique serait certainement un plus, sinon il y a un risque qu'il passe dans le referer si tu passes de ta zone admin à un autre site. Mais là, ça voudra dire que le site gènère des CSRF dynamiquement :shock:

ViPHP
xTG
ViPHP | 7331 Messages

21 janv. 2011, 08:34

Ouah mettre un lien dans une zone admin vers un autre serveur que l'actuel !
J'avoue que j'avais encore jamais pensé à faire une telle bêtise. x)

devlop78
Invité n'ayant pas de compte PHPfrance

21 janv. 2011, 16:49

Un lien ? Pas forcément. Tu es sur ta zone admin, et tu te dis ... tiens ! Je vais sur forum.phpfrance.com ... et Vlan ! PhpFrance a ton token ... mais il a pas ta session ... Mais on sait qu'ils sont vicieux sur ce forum là et qu'ils génèrent des images CSRF ^^

ViPHP
AB
ViPHP | 5818 Messages

21 janv. 2011, 20:30

Concernant les zones admin, je ne vois pas bien l'utilité d'un token. Si un admin quitte son application sans avoir mis fin à sa session et que quelqu'un passe juste derrière lui, avec ou sans token, ça sera pareil. Le plus important selon moi dans les zones admin est de sécuriser la connexion à l'espace administrateur et d'interdire que l'identifiant de session puisse passer dans l'url.