Tengo un sitio donde un usuario envía un mensaje a través de AJAX a un archivo llamado like.php. En este archivo de los usuarios de mensaje se envía a una base de datos y, a continuación, envía un enlace de vuelta al usuario. En mi código Javascript que he deshabilitado el cuadro de texto que el usuario escribe en cuando envía la petición AJAX.

El único problema es que un usuario malicioso puede constantemente enviar peticiones POST a like.php, y la inundación de mi base de datos. Así que me gustaría implementar simple protección contra las inundaciones.

Yo realmente no quieren la molestia de otra tabla de base de datos de registro de los usuarios de IPs y tal… como si ellas están inundando mi sitio habrá una gran cantidad de base de datos de lectura/escritura se ralentice. Pensé sobre el uso de sesiones, como una sesión que contiene una marca de tiempo que se comprueba cada vez que se envían los datos a like.php, y si la hora actual es antes de la hora de registro permitirá añadir datos a la base de datos, de lo contrario enviar un error y bloquearlos. Si se les permite entrar algo en la base de datos, la actualización de su sesión con una nueva marca de hora.

¿Qué te parece? Sería la mejor manera de ir sobre ella o hay alternativas más fáciles?

Gracias por la ayuda. 🙂

Un spam-bot no reconocerá la cookie de sesión, lo que, posiblemente, no mediante una sesión. También podría alterar maliciosamente la ID de sesión cada vez, dejando sin posibilidad de seguirle la pista. Usted probablemente no va a obtener alrededor de algún tipo de registro IP.
Obligar al usuario a ser firmado en para enviar el mensaje? (acepte sólo like.php's desde firmado en cuentas), a Continuación, dejar que los usuarios enviar demasiados en un asignado cantidad de tiempo?
Gracias por tus sugerencias. Como dije en una de las respuestas de comentarios no me como un usuario del sistema como el punto principal de este sitio es que es rápido y sin complicaciones. Voy a tener que mirar en la dirección IP de registro 🙂
Este es el tipo de cosa memcached es perfecto para. Rápido, ligero, y si pierdes los datos, que no es gran cosa. De la búsqueda para «limitante» aquí: carsonified.com/blog/dev/…

OriginalEl autor VIVA LA NWO | 2010-06-11

7 Comentarios

  1. 5

    El uso de un token. Generar el token y agregar a la página de origen de la solicitud. En like.php de comprobar que la solicitud contiene un token válido, lo que significa que viene de tu página en lugar de una externa Publicar directamente.

    Entonces, lo más importante, que invalida el token una vez que se ha utilizado. Adjuntar el token a la sesión también se agrega otra capa de anti-bot código. (Primitivo bots no las cookies.) Ahora, avanzados robots todavía funcionan, pero sería más trabajo para el bot de autor.
    Esto es realmente perfecto. Pero, ¿cómo generar el token? Sólo un hash a partir de un número aleatorio o algo? Y también cómo se like.php saber qué token es válido o no? Debo envió a pesar de una SESIÓN? 🙂 Saludos!
    Lo que está deteniendo a alguien de la visualización de la página una vez, obtener el token, a continuación, la automatización de las solicitudes/POST con el token válido?
    Esto solo convierte el script del POST bucle en un GET&POST bucle.

    OriginalEl autor

  2. 7

    Sesión es el más fácil de hacer esto, y la que tiene menos sobrecarga así. Usted puede almacenar dos bits de datos en la sesión, marca de tiempo del último post, y la ip, el post está llegando desde. Aquí es cómo usted verificación de legitimidad:

    session_start();
    if(isset($_SESSION['ip']) && $_SESSION['last_post'] + MININTERVAL < time()) die('too early');
    
    $_SESSION['last_post'] = time();
    $_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
    //store the message
    Esta clase de obras… pero incluso después de 10 minutos de que todavía no me deja enviar un comentario (que es lo que estoy usando esto para) ¿cuánto tiempo es un MININTERVAL? Parece más de un minuto, ¿hay alguna otra manera de agregar un minuto para $_SESSION['last_post']?
    MININTERVAL es un marcador de posición para el número de segundos que desea utilizar. Si desea establecer un 2 minutos de intervalo de cambio de la línea de if(isset($_SESSION['ip']) && $_SESSION['last_post'] + 120 < time()) die('too early');
    Majid hizo al revés: if(isset($_SESSION[‘ip’]) && ($_SESSION[‘last_post’] + MININTERVAL) > time()) die(‘demasiado pronto’);
    fijo. Gracias!
    no, no es así como sesiones de trabajo. Un vacío de la sesión se crea si no existe ninguna cookie de sesión presente en la solicitud, es decir, la primera solicitud de un visitante envía, para lo cual es bien no die. Las solicitudes posteriores tendrán una cookie de sesión, y session_start() hará que el $_SESSION variable para ser llenados con cualquier valor que se asigna a la última vez-que es last_post y ip.

    OriginalEl autor

  3. 3

    Otra manera de hacer esto es escribir un formulario oculto de entrada a la página (que llama like.php) usando jQuery. Un bot no ser el uso de javascript por lo que su campo de formulario oculto no existen.

    De verificación para el campo oculto (asignar un valor y un nombre) y si existe, entonces golpeó la base de datos con la solicitud.

    Otra manera; código de un elemento oculto en la página (<input style='display:none;' name='nospam' value='' />). Un bot que se auto-rellenar todos los campos en el formulario, por lo que usted acaba de comprobar si este campo se rellena – un usuario no puede ver lo que usted sabe que es un bot si tienes contenido.

    Establecer el estilo (display:none;) usando jQuery tho… de nuevo, un bot no ver el jQuery, así que creo que este no es de fiar formulario de entrada.

    Puede que desee especificar un ‘esta página requiere javascript para ejecutar un aviso en algún lugar por el usuario. Algunas sugerencias alternativas. Después de todo – le dijo ‘simple’ 😉

    OriginalEl autor

  4. 3

    Usted no necesita ir a través de todo el archivo de registro. Lugar:

    <?php
    define("FLOODPOOL", ".");
    define("FLOODPOOL_LIMIT", 30);
    define("FLOODPOOL_DURATION", 60 * 60 * 24);
    define("FLOODPOOL_AUTOCLEAN", true);
    
    //Record and check flood.
    //Return true for hit.
    function floodpool_check($id){
        $fp = fopen(FLOODPOOL . DIRECTORY_SEPARATOR . 'fp_' . basename($id), 'a+');
        fwrite($fp, pack('L', time()));
        if(fseek($fp, -4 * FLOODPOOL_LIMIT, SEEK_END) === -1) {
            return false;
        }
        $time = reset(unpack('L', fread($fp, 4)));
        fclose($fp);
        if(time() - $time < FLOODPOOL_DURATION) {
            if(FLOODPOOL_AUTOCLEAN){
                @floodpool_clean();
            }
            return true;
        }
        return false;
    }
    
    
    //Clean the pool.
    function floodpool_clean(){
        $handle = opendir(FLOODPOOL);
        while(false!==($entry=readdir($handle))){
            $filename = FLOODPOOL . DIRECTORY_SEPARATOR . $entry;
            if(time() - filectime($filename) > FLOODPOOL_DURATION && substr($entry, 0, 3) === 'fp_'){
                unlink($filename);
            }
        }
        closedir($handle);
    }

    Ejemplo de uso:

    if(floodpool_check($_SERVER['REMOTE_ADDR'])){
        header("HTTP/1.1 429 Too Many Requests");
        exit("Hit some *");
    }

    OriginalEl autor

  5. 2

    Bueno he hecho un script para manejar por núcleo sólo se pide (ninguna sesión o solicitudes otras solicitudes que no son de llamar el núcleo). Si usted tiene un vistazo a google vas a encontrar scripts/clases que va a matar a su servidor debido a la alta carga cada vez. El hecho, que muchos usan Sesiones y tal vez TAMBIÉN de SQL y Base de datos te permitirá obtener una protección de inundaciones como un servidor de asesino. También el hecho de que las Sesiones de la necesidad de una Cookie (o GET SID) de lo que se puede manipular Sesiones fácil conseguir un nuevo IDENTIFICADOR de SESIÓN.

    Mi función es basado en texto y hacer un manejo sencillo. Lo malo es que tal vez tenga que utilizar un CronJob para eliminar ips a partir de tiempo al tiempo. En comparación con otras secuencias de comandos de su alrededor de 10* más rápido (y más guardar de sesiones).

    No sé si es realmente útil a todos. 😉
    Usted tal vez como para cambiar las rpm del valor a menos o/y también el 200 req. Mi configuración es una prohibición para un bot haciendo intervalo de solicitudes en <=6 segundos.

    <?php
    function ht_request_limiter() {
    if (!isset($_SERVER['REMOTE_ADDR'])) { return; } //Maybe its impossible, however we check it first
    if (empty($_SERVER['REMOTE_ADDR'])) { return; } //Maybe its impossible, however we check it first
    $path = '/your/path/ipsec/'; //I use a function to validate a path first and return if false...
    $path = $path.$_SERVER['REMOTE_ADDR'].'.txt'; //Real file path (filename = <ip>.txt)
    $now = time(); //Current timestamp
    if (!file_exists($path)) { //If first request or new request after 1 hour /24 hour ban, new file with <timestamp>|<counter>
    if ($handle = fopen($path, 'w+')) {
    if (fwrite($handle, $now.'|0')) { chmod($path, 0700); } //Chmod to prevent access via web
    fclose($handle);
    }
    }
    else if (($content = file_get_contents($path)) !== false) { //Load existing file
    $content = explode('|',$content); //Create paraset [0] -> timestamp  [1] -> counter
    $diff = (int)$now-(int)$content[0]; //Time difference in seconds from first request to now
    if ($content[1] == 'ban') { //If [1] = ban we check if it was less than 24 hours and die if so
    if ($diff>86400) { unlink($path); } //24 hours in seconds.. if more delete ip file
    else {
    header("HTTP/1.1 503 Service Unavailable");
    exit("Your IP is banned for 24 hours, because of too many requests.");
    }
    }
    else if ($diff>3600) { unlink($path); } //If first request was more than 1 hour, new ip file
    else {
    $current = ((int)$content[1])+1; //Counter + 1
    if ($current>200) { //We check rpm (request per minute) after 200 request to get a good ~value
    $rpm = ($current/($diff/60));
    if ($rpm>10) { //If there was more than 10 rpm -> ban (if you have a request all 5 secs. you will be banned after ~17 minutes)
    if ($handle = fopen($path, 'w+')) {
    fwrite($handle, $content[0].'|ban');
    fclose($handle);
    //Maybe you like to log the ip once -> die after next request
    }
    return;
    }
    }
    if ($handle = fopen($path, 'w+')) { //else write counter
    fwrite($handle, $content[0].'|'.$current .'');
    fclose($handle);
    }
    }
    }
    }

    Edit: Mi manera de probar la solicitud vez fue con microtime y simular 10’000 usuarios. Pido a google y probado (como ejemplo) http://technitip.net/simple-php-flood-protection-class

    Así que no sé lo que debería ser simple no? Tiene alrededor de 3 Solicitudes SQL en un momento como:

    $this -> user_in_db($ip))
    $this->user_flooding($ip);
    $this->remove_old_users();

    Es tal vez el suministro de más funciones, pero todos de fiar a los usuarios utilizar servertime para nada. 😉

    La secuencia de comandos aquí tiene las condiciones de carrera cuando varias copias de la secuencia de comandos se ejecutan al mismo tiempo y de procesamiento de las solicitudes de la misma dirección IP. Contador va a ser, a veces, sólo se incrementa de una vez por dos o más solicitudes, y a veces se puede recibir mensajes de error de la unlink() no (otro script ha eliminado al mismo tiempo). una pregunta relacionada con la

    OriginalEl autor

  6. 0

    Pensé acerca del uso de las sesiones, como
    una sesión que contiene un
    marca de tiempo que se comprueba cada vez que
    enviar datos a like.php

    Esto no deja de bots como se puede recibir y enviar la misma cookies que hacen los usuarios.

    Usted realmente debe tener los usuarios iniciar sesión en un sistema. Parece ser que vale la pena proteger el acceso. Usted también podría considerar la limitación de mensajes por minuto por ip, sino de varios bots todavía podría enviar muchos mensajes de spam.

    Si usted no desea implementar un inicio de sesión a continuación, muchos sitios utilizan captcha para intentar reducir estos intentos.

    http://www.phpcaptcha.org/

    Gracias. En realidad no me gusta la idea de un usuario de sistema o de un CAPTCHA como el objetivo principal de el sitio está pensado para ser rápido y rápido para enviar un mensaje. Parece que me voy a tener que ir con la dirección IP de registro, después de todo.

    OriginalEl autor

  7. 0

    Si desea detener la inundación de una página de búsqueda que usted puede tratar de esta manera:

    $flood_protection_interval = 2;
    session_start();
    if(
    isset($_SESSION['ip']) && 
    $_SESSION['counter'] > 10 &&
    $_SESSION['last_post'] + $flood_protection_interval > time()
    ){
    //$_SESSION['counter'] = 0; //Use this if you want to reset counter
    die("<pre>\n\n\n\t<b>FLOOD PROTECTION</b>");
    }
    $_SESSION['counter']++;
    $_SESSION['last_post'] = time();
    $_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];

    Así que si el visitante busca 10 veces bajo por ejemplo, 2 segundos, se detiene!

    OriginalEl autor

Dejar respuesta

Please enter your comment!
Please enter your name here