De l’inutilité de la fonction PHP sleep pour protéger des attaques brute force (exemple avec Prestahop)

Le couple adresse email / mot de passe est le sésame permettant d’accéder à presque l’ensemble des activités numériques d’un individu : messagerie, réseaux sociaux, documents, extranets, interface client des boutiques en-ligne…

Les applications web se doivent de garantir la sécurité de leurs utilisateurs. En plus du minimum exigible (hachage et salage des mots de passe en base de données, protections contre les injections SQL, les attaques de type XSS et CSRF…), les développeurs tentent souvent de trouver des astuces permettant de protéger mieux les utilisateurs de leurs programmes.

Tenter de se protéger des attaque par force brute…

Ainsi, on trouve le code suivant dans le système de connexion à l’interface client de Prestashop, la très populaire plateforme e-commerce open-source :

Comme le commentaire l’indique, les développeurs de Prestashop tentent de protéger leurs utilisateurs d’une attaque par force brute.
L’idée est que pour obtenir un accès à l’interface client, le pirate va utiliser un robot qui va tester méthodiquement et à très grande vitesse tous les mots de passe possibles (dans les faits, ce types de robots testent dans un premier temps les mot de passe les plus communs grâce à des listes pré-établies).
Bien que le concept soit bon, l’appel à sleep est inutile. Les serveurs web sont multithreads et les robots d’attaque le sont aussi. Ces derniers lanceront de nombreuses connexions parallèles et n’attendront pas de savoir si le mot de passe est correct ou non pour en tester un nouveau.

Pire cette implémentation est dangereuse car, en plus de ralentir l’affichage de la page indiquant une erreur de saisie aux utilisateurs légitimes, elle bloquera le thread le temps du sleep (ici une seconde) et favorisera ainsi les attaques par déni de service. Un attaquant souhaitant engorger le site (ce qui aura pour conséquence de le ralentir voir de le rendre inaccessible) lancera de très nombreuses requêtes de connexion avec un mauvais mot de passe. L’effet sera plus important et l’attaque d’autant plus efficace sur cette page grâce au blocage du à l’appel à la fonction sleep.

Se protéger efficacement

Commençons par supprimer de nos codes sources ces appels à sleep aussi inutiles que dangereux. Les développeurs de Prestashop ont pris les devants et à l’heure ou j’écris ces lignes la version de développement de la plateforme e-commerce ne contient plus le code incriminé.

Adaptons maintenant l’idée d’empêcher les tentatives de connexion trop fréquentes à l’environnement multithreads des serveurs web. Commençons par stocker chaque erreur de connexion ainsi que la date à laquelle elle se produit et l’utilisateur qu’elle concerne dans une base de données ou mieux avec memcached. Si pour un même utilisateur une tentative de connexion arrive trop rapidement après l’une ayant échouée, disons au bout d’une seconde après le premier échec, de 5 après le deuxième, de 10 après le troisième…, exigeons que l’utilisateur prouve qu’il est bien humain (ex. : en ajoutant un CAPTCHA en plus des champs login et password). Si les echecs provenant d’une même adresse IP sont systématiques, on peut blacklister cette adresse car elle est probablement utilisée par un assaillant.

Dernier point, inciter voir exiger que vos utilisateurs optent pour un mot de passe fort diminue drastiquement les risques de compromission par force brute. N’hésitez pas à afficher des jauges de sûretés auprès du champ de saisie de mot de passe du formulaire d’inscription.

3 Comments

  1. Stocker le dernier essai en session ne me semble pas une très bonne idée car en règle général les robots d'attaque ne renvoient pas les cookies ni les SESSID dans l'URL. Même vérifier l'IP n'est pas si génial que ça car les robots peuvent en changer facilement (voir à chaque connexion) avec des proxys et TOR.

    Reply

  2. Effectivement, je n'ai pas précisé que si le client ne gère pas les cookies, la connexion au site est bloquée. Du coup, les robots qui les refusent sont naturellement exclus. Ce n'est pas une solution pour ceux qui gèrent les SESSID mais dans mon cas ça fonctionne.

    Reply

Leave a Reply