2009-02-01 10 views
7

Quel est le meilleur moyen d'empêcher les bots, les utilisateurs malveillants, etc. d'exécuter les scripts PHP trop rapidement? Est-ce correct si j'utilise les fonctions usleep() ou sleep() pour faire simplement "rien" pendant un moment (juste avant que le code désiré ne s'exécute), ou est-ce stupide et il y a de meilleurs moyens pour cela?Retarder l'exécution du script PHP

Exemple:

function login() { 
//enter login code here 
} 

function logout() { 
//enter logout code here 
} 

Si je viens de mettre, par exemple, usleep(3000000) avant que les codes de connexion et de déconnexion, est-ce correct, ou y at-il de meilleures façons plus sage de réaliser ce que je veux atteindre?

modifier: Sur la base des suggestions ci-dessous, ne puis usleep ou sleep n'amènent le processeur à se désengager du script en cours en cours d'exécution par l'utilisateur courant, ou il ne provoque la désolidarisation du service entier? C'est-à-dire que si un utilisateur + script appelle un sleep/usleep, tous les utilisateurs simultanés + scripts seront-ils également retardés?

Répondre

8

La façon dont la plupart des serveurs web travail (Apache par exemple) est de maintenir une collection de threads de travail. Lorsqu'un script PHP est exécuté, un thread exécute le script PHP. Lorsque votre script exécute sleep(100), le script prend 100 secondes à exécuter. Cela signifie que votre thread de travail est lié pendant 100 secondes.

Le problème est, vous avez un nombre très limité de travailleurs-fils - dire que vous avez 10 fils de discussion, et 10 personnes se connecter - maintenant votre serveur web ne peut pas servir d'autres réponses ..

La meilleure façon de Les connexions de taux-limites (ou autres actions) consistent à utiliser une sorte de stockage rapide en mémoire (memcached est parfait pour cela), mais cela nécessite un processus séparé et est assez compliqué (vous pouvez le faire si vous utilisez quelque chose comme Facebook ..).

Plus simple, vous pouvez avoir une table de base de données qui stocke user_id ou ip_address, first_failed et failure_counter.

Chaque fois que vous obtenez un échec de connexion, vous (dans le code pseudo) ferait:

if (first_failed in last hour) and (failure_counter > threshold): 
    return error_403("Too many authentication failures, please wait") 
elseif first_failed in last hour: 
    increment failure_counter 
else: 
    reset first_failed to current time 
    increment failure_counter 

Peut-être pas le plus efficace, et il y a de meilleures façons, mais il devrait cesser de brute-forcer assez bien. L'utilisation de memcached est fondamentalement la même, mais la base de données est remplacée par memcached (qui est plus rapide)

1

Votre méthode proposée forcera tous les utilisateurs à attendre inutilement avant de vous connecter.

La plupart des serveurs LAMP (et la plupart des routeurs/commutateurs, en fait) sont déjà configurés pour empêcher des attaques par déni de service. Ils le font en refusant plusieurs demandes consécutives de la même adresse IP.

1

Vous ne voulez pas mettre un sommeil dans votre php. Cela réduira considérablement le nombre de demandes simultanées que votre service peut traiter puisque vous aurez des connexions en attente.

La plupart des serveurs HTTP ont des fonctionnalités que vous pouvez activer pour éviter les attaques DoS, mais vous devez simplement suivre les adresses IP que vous avez vues trop souvent et leur envoyer un message leur demandant d'attendre une seconde. . Si, pour une raison quelconque, vous ne pouvez pas compter sur REMOTE_ADDR étant spécifique à l'utilisateur (tout le monde derrière le même pare-feu, etc.), vous risquez de rencontrer un problème dans le formulaire de connexion. , facteur un nombre) que vous pouvez vérifier rapidement sur le côté serveur (avec une multiplication rapide).

2

pour arrêter les robots, les utilisateurs malveillants, etc. d'exécuter des scripts PHP trop vite?

Je voudrais d'abord vous demander ce que vous essayez vraiment d'éviter? S'il s'agit d'attaques par déni de service, je dois dire que vous ne pouvez rien faire si vous êtes limité par ce que vous pouvez ajouter aux scripts PHP. L'état de l'art est tellement au-delà de ce que nous, en tant que programmeurs, pouvons nous protéger. Commencez à regarder les outils sysadmin conçus à cet effet. Ou essayez-vous de limiter votre service afin que de vraies personnes puissent y accéder, mais pas les robots? Si oui, je regarderais quelques techniques "captcha". Ou essayez-vous d'empêcher les utilisateurs d'interroger votre site chaque seconde à la recherche de nouveau contenu? Si c'est le cas, je chercherais à fournir un flux RSS ou une autre façon de les notifier afin qu'ils ne mangent pas votre bande passante.

Ou est-ce autre chose?

En général, je dirais que ni sleep() ni usleep() n'est un bon moyen.

-
BMB