2013-04-16 7 views
2

Я заметил, что некоторые пользователи перегружают мой сайт, загружая несколько файлов (например, 500 файлов одновременно) и открывая больше страниц в малой продолжительности, я хочу показать captcha if неожиданная навигация, обнаруженная пользователем.Показать, когда обнаружена непредвиденная навигация, чтобы предотвратить злоупотребление служебным положением

Я знаю, как реализовать Captcha, но я не могу понять, что лучше всего подходит для обнаружения трафика с использованием (PHP)?

ответ

5

Общий подход заключается в использовании что-то вроде Memcached для хранения запросов на минуте основе, я с открытым исходным кодом маленького класса, который достигает эта цель: php-ratelimiter

Если вы заинтересованы в более подробном объяснении того, почему запросы необходимо хранить на минутной основе, check this post.

Так, чтобы подвести итог, ваш код может закончить тем, что, как это:

if (!verifyCaptcha()) { 
    $rateLimiter = new RateLimiter(new Memcache(), $_SERVER["REMOTE_ADDR"]); 
    try { 
     $rateLimiter->limitRequestsInMinutes(100, 5); 
    } catch (RateExceededException $e) { 
     displayCaptcha(); 
     exit; 
    } 
} 

На самом деле, код основан на поминутной основе, но вы вполне можете легко адаптировать это быть на за 30 секунд основа:

private function getKeys($halfminutes) { 
    $keys = array(); 
    $now = time(); 
    for ($time = $now - $halfminutes * 30; $time <= $now; $time += 30) { 
     $keys[] = $this->prefix . date("dHis", $time); 
    } 
    return $keys; 
} 
+2

Это простой класс, который выглядит хорошо. Thx для обмена! –

2

Введение

аналогичный вопрос можно ответить, прежде чем Prevent PHP script from being flooded, но это могло бы не будет достаточных оснований:

  • Он использует $_SERVER["REMOTE_ADDR"] и они являются некоторые общие соединения имеют одинаковый Public IP Address
  • Есть так много Firefox addon, которые могут позволяет пользователям использовать несколько прокси-сервер для каждого запроса

Несколько запросов! = Несколько Загрузить

Предотвращение множественного запроса полностью отличается от множественного скачивания почему?

Lest Представьте файл 10MB, который будет принимать 1min для загрузки, если вы ограничить доступ пользователей сказать 100 request per min, что это означает, что вы получили доступ к пользователю, чтобы загрузить

10MB * 100 per min 

Чтобы устранить эту проблему, вы можете посмотреть на Download - max connections per user?.

Multiple Запрос

Назад к странице доступа вы можете использовать SimpleFlood, которые проходят memcache ограничить пользователей в секунду.Он использует cookies для решения общей проблемы соединения и пытается получить реальный IP-адрес

$flood = new SimpleFlood(); 
$flood->addserver("127.0.0.1"); // add memcache server 
$flood->setLimit(2); // expect 1 request every 2 sec 
try { 
    $flood->check(); 
} catch (Exception $e) { 
    sleep(2); // Feel like wasting time 
    // Display Captcher 
    // Write Message to Log 
    printf("%s => %s %s", date("Y-m-d g:i:s"), $e->getMessage(), $e->getFile()); 
} 

Пожалуйста, обратите внимание, что SimpleFlood::setLimit(float $float); принимает поплавки, так что вы можете иметь

$flood->setLimit(0.1); // expect 1 request every 0.1 sec 

Класс Б

class SimpleFlood extends \Memcache { 
    private $ip; 
    private $key; 
    private $prenalty = 0; 
    private $limit = 100; 
    private $mins = 1; 
    private $salt = "I like TO dance A #### Lot"; 

    function check() { 
     $this->parseValues(); 
     $runtime = floatval($this->get($this->key)); 
     $diff = microtime(true) - $runtime; 
     if ($diff < $this->limit) { 
      throw new Exception("Limit Exceeded By : $this->ip"); 
     } 
     $this->set($this->key, microtime(true)); 
    } 

    public function setLimit($limit) { 
     $this->limit = $limit; 
    } 

    private function parseValues() { 
     $this->ip = $this->getIPAddress(); 
     if (! $this->ip) { 
      throw new Exception("Where the hell is the ip address"); 
     } 

     if (isset($_COOKIE["xf"])) { 
      $cookie = json_decode($_COOKIE["xf"]); 
      if ($this->ip != $cookie->ip) { 
       unset($_COOKIE["xf"]); 
       setcookie("xf", null, time() - 3600); 
       throw new Exception("Last IP did not match"); 
      } 

      if ($cookie->hash != sha1($cookie->key . $this->salt)) { 
       unset($_COOKIE["xf"]); 
       setcookie("xf", null, time() - 3600); 
       throw new Exception("Nice Faking cookie"); 
      } 
      if (strpos($cookie->key, "floodIP") === 0) { 
       $cookie->key = "floodRand" . bin2hex(mcrypt_create_iv(50, MCRYPT_DEV_URANDOM)); 
      } 
      $this->key = $cookie->key; 
     } else { 
      $this->key = "floodIP" . sha1($this->ip); 
      $cookie = (object) array(
        "key" => $this->key, 
        "ip" => $this->ip 
      ); 
     } 
     $cookie->hash = sha1($this->key . $this->salt); 
     $cookie = json_encode($cookie); 
     setcookie("xf", $cookie, time() + 3600); // expire in 1hr 
    } 

    private function getIPAddress() { 
     foreach (array(
       'HTTP_CLIENT_IP', 
       'HTTP_X_FORWARDED_FOR', 
       'HTTP_X_FORWARDED', 
       'HTTP_X_CLUSTER_CLIENT_IP', 
       'HTTP_FORWARDED_FOR', 
       'HTTP_FORWARDED', 
       'REMOTE_ADDR' 
     ) as $key) { 
      if (array_key_exists($key, $_SERVER) === true) { 
       foreach (explode(',', $_SERVER[$key]) as $ip) { 
        if (filter_var($ip, FILTER_VALIDATE_IP) !== false) { 
         return $ip; 
        } 
       } 
      } 
     } 

     return false; 
    } 
} 

Заключение

Это основные доказать концепции и дополнительные слои могут быть добавлены к нему, таким как

  • установить различный предел для различия URLS
  • Добавить поддержку наказаний, где вы блокируете пользователь для определенного количества минут или часы
  • обнаружения и различные предельная для Tor соединений
  • т.д.
+0

Спасибо за хорошее объяснение ... – 2013-04-25 05:58:18

1

Я думаю, у В этом случае вы можете использовать сеансы. Инициализировать сеанс для хранения временной метки [использовать микросессию для получения лучших результатов], а затем получить временную метку новой страницы. Разницу можно использовать для анализа частоты посещений страниц и отображения капчей.

Вы также можете запустить счетчик на посещаемых страницах и использовать 2-мерный массив для хранения страницы и отметки времени. Если значение посещаемых страниц резко увеличивается, вы можете проверить разницу по времени.

+0

Я также пытался сделать это, используя сеанс. после его реализации я столкнулся с некоторыми накладными расходами при расчете числа посещений и обновлении их для каждого нового посещения ... – 2013-04-21 18:16:39

+0

Ну, не будет большого количества лиц, злоупотребляющих трафиком, я думаю. Вы можете создать для него таблицу базы данных, и после того, как некоторые IP-адреса выглядят безопасными вышеприведенными вычислениями, добавьте их в список. Кроме того, вы можете добавить неверные IP-адреса в базу данных с помощью какого-либо отличительного ключа. Поэтому, если вы сразу узнаете какой-то IP-адрес как плохое выполнение вычислений или вместо этого отображать штрих-код после каждого x посещений страниц за ip –

+0

Но иногда хороший пользователь хочет загрузить список файлов, но не всегда, поэтому мне нужно показать captcha только при обнаружении неожиданного поведения – 2013-04-22 09:07:04

 Смежные вопросы

  • Нет связанных вопросов^_^