2009-02-01 73 views
7

¿Cuál es la mejor manera de evitar que bots, usuarios maliciosos, etc. ejecuten scripts de PHP demasiado rápido? ¿Está bien si uso las funciones usleep() o sleep() para simplemente hacer "nada" por un tiempo (justo antes de que se ejecute el código deseado), o es así de estúpido y hay mejores formas de hacerlo?Retrasar la ejecución del script PHP

Ejemplo:

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

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

Si acabo de poner, por ejemplo, usleep(3000000) antes de que los códigos de conexión y desconexión, es que bien, o hay formas mejores y más acertadas de lograr lo que quiero lograr?

edición: Sobre la base de las sugerencias a continuación, hace entonces usleep o sleep única causa que el procesador se desacople de la secuencia de comandos actual que está siendo ejecutado por el usuario actual, o se causa que se desacople de todo el servicio? es decir, si un script + de usuario invoca un sleep/usleep, ¿se retrasarán también todos los scripts + usuarios simultáneos?

Respuesta

8

La forma más servidores web de trabajo (por ejemplo Apache) es mantener una colección de subprocesos de trabajo. Cuando se ejecuta un script PHP, un hilo ejecuta el script PHP.

Cuando su script hace sleep(100), el script tarda 100 segundos en ejecutarse .. Eso significa que su hilo de trabajo está atado durante 100 segundos.

El problema es, usted tiene un número muy limitado de trabajadores-hilos - dice que tiene 10 hilos, y 10 personas que identificarte - ahora su servidor web no puede servir a cualesquiera nuevas respuestas ..

La mejor manera de el límite de velocidad de inicio de sesión (u otras acciones) es utilizar algún tipo de almacenamiento rápido en la memoria (memcached es perfecto para esto), pero eso requiere ejecutar un proceso separado y es bastante complicado (puede hacer esto si ejecuta algo como Facebook ..).

más simple, usted podría tener una tabla de base de datos que almacena user_id o ip_address, first_failed y failure_counter.

Cada vez que tenga un inicio de sesión fallido, usted (en pseudocódigo) haría:

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 

Quizás no es el más eficiente, y hay mejores maneras, pero debe dejar de fuerza bruta bastante bien. El uso de memcached es básicamente el mismo, pero la base de datos se reemplaza por memcached (que es más rápido)

1

Su método sugerido llevará a todos los usuarios que esperar innecesariamente antes de iniciar sesión.

mayoría de los servidores LAMP (y la mayoría de los routers/switches, en realidad) ya están configurados para evitar ataques de Denegación de Servicio. Lo hacen al denegar múltiples solicitudes consecutivas desde la misma dirección IP.

1

No querrás dormir en tu php. Si lo hace, reducirá en gran medida la cantidad de solicitudes simultáneas que su servidor puede gestionar, ya que tendrá conexiones abiertas esperando.

La mayoría de los servidores HTTP tienen funciones que puedes habilitar para evitar ataques DoS, pero si no, simplemente debes rastrear direcciones IP que has visto demasiadas veces y enviarles un 403 Prohibido con un mensaje pidiéndoles que esperen un segundo .

Si por alguna razón no puede contar con que REMOTE_ADDR sea específico del usuario (todos detrás del mismo firewall, etc.) podría probar un desafío en el formulario de inicio de sesión y hacer que el navegador remoto haga un cálculo extendido en él (por ejemplo , factoriza un número) que puedes verificar rápidamente en el lado del servidor (con multiplicación rápida).

2

para detener a los bots, usuarios maliciosos, etc. de ejecutar scripts de php demasiado rápido?

Primero pregunto qué es lo que realmente está tratando de evitar? Si se trata de ataques de denegación de servicio, entonces tendría que decir que no hay nada que pueda hacer si está limitado por lo que puede agregar a los scripts de PHP. El estado del arte es mucho más allá de lo que nosotros, como programadores, podemos proteger. Comience a buscar las herramientas de administrador de sistemas diseñadas para este fin.

¿O está tratando de limitar su servicio para que la gente real pueda acceder a él, pero los bots no? Si es así, miraría algunas técnicas de "captcha".

¿O está tratando de evitar que los usuarios revisen su sitio cada segundo buscando nuevos contenidos? Si es así, investigo proporcionando un canal RSS u otra forma de notificarlos para que no consuman tu ancho de banda.

¿O es algo más?

En general, yo diría que ni sleep() ni usleep() es una buena manera.

-
BMB

Cuestiones relacionadas