| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- <?php
- /**
- * Classe `blacklist`
- *
- * Cette classe gère la mise en liste noire des adresses IP en fonction des tentatives
- * répétées d'accès à des ressources protégées. Elle permet de :
- * - Suivre les tentatives d'accès via un fichier de log.
- * - Blacklister les adresses IP après un certain nombre de tentatives.
- * - Vérifier si une adresse IP est blacklistée.
- * - Gérer les extensions d'URL interdites.
- */
- class blacklist {
- /**
- * Fichier de log des tentatives.
- *
- * @var string
- */
- private static $log_file = '../blacklist/ip_attempts.log';
- /**
- * Fichier contenant les IP blacklistées.
- *
- * @var string
- */
- private static $blacklist_file = '../blacklist/ip.txt';
- /**
- * Nombre maximum de tentatives autorisées avant blacklist.
- *
- * @var int
- */
- private static $max_attempts = 5;
- /**
- * Fenêtre de temps pour les tentatives (en secondes).
- *
- * @var int
- */
- private static $time_window = 10 * 60; // 10 minutes en secondes
- /**
- * Exécute la vérification de la blacklist.
- *
- * @return array|null Retourne un tableau d'erreur ou NULL si aucune action n'est nécessaire.
- */
- public static function execute() {
- return self::check();
- }
- /**
- * Vérifie si l'adresse IP est une IPv4 valide.
- *
- * @return bool TRUE si l'adresse IP est valide, FALSE sinon.
- */
- public static function isValidIPv4() {
- // Vérification de l'existence de la clé HTTP_HOST avant utilisation
- $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'undefined';
- // Ajout d'un journal pour les cas où HTTP_HOST est manquant
- if ($host != 'undefined') {
- $isDev = (strpos($_SERVER['HTTP_HOST'], 'local.') === 0); // Vérifie si c'est une URL locale de développement
- return $isDev ? TRUE : filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== FALSE;
- } else {
- return FALSE;
- }
- }
- /**
- * Récupère l'URL complète de la requête.
- *
- * @return string L'URL complète.
- */
- private static function getFullUrl() {
- $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') ? 'https://' : 'http://';
- return $protocol . $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'];
- }
- /**
- * Vérifie si l'extension de l'URL est blacklistée.
- *
- * @return bool TRUE si l'extension est blacklistée, FALSE sinon.
- */
- private static function isBlacklistExtention() {
- $uri = $_SERVER['REQUEST_URI'];
- $blackListExtention = ['php'];
- $extension = pathinfo(parse_url($uri, PHP_URL_PATH), PATHINFO_EXTENSION);
- return in_array(strtolower($extension), $blackListExtention);
- }
- /**
- * Lit les tentatives existantes depuis le fichier de log.
- *
- * @return array Un tableau des tentatives.
- */
- private static function readBlacklist() {
- $attempts = [];
- if (file_exists(self::$log_file)) {
- $lines = file(self::$log_file, FILE_IGNORE_NEW_LINES);
- foreach ($lines as $line) {
- list($ip, $timestamp) = explode(',', $line);
- $attempts[] = ['ip' => $ip, 'timestamp' => strtotime($timestamp)];
- }
- }
- return $attempts;
- }
- /**
- * Vérifie si une IP est déjà blacklistée.
- *
- * @param string $_ip L'adresse IP à vérifier.
- * @return bool TRUE si l'IP est blacklistée, FALSE sinon.
- */
- private static function checkBlacklist(string $_ip) {
- $blacklisted = FALSE;
- if (file_exists(self::$blacklist_file)) {
- $blacklisted_ips = file(self::$blacklist_file, FILE_IGNORE_NEW_LINES);
- $blacklisted = in_array($_ip, $blacklisted_ips);
- }
- return $blacklisted;
- }
- /**
- * Ajoute une tentative pour une IP dans le fichier de log.
- *
- * @param string $_ip L'adresse IP à ajouter.
- * @return void
- */
- private static function addBlacklist(string $_ip) {
- file_put_contents(self::$log_file, "$_ip," . date('Y-m-d H:i:s') . ", " . $_SERVER["REQUEST_METHOD"] . "," . self::getFullUrl() . "\n", FILE_APPEND);
- }
- /**
- * Vérifie si une IP doit être blacklistée et effectue les actions nécessaires.
- *
- * @return array|null Retourne un tableau d'erreur ou NULL si aucune action n'est nécessaire.
- */
- private static function check() {
- if (self::isBlacklistExtention()) {
- $now = time();
- $time_window = self::$time_window;
- $attempts = self::readBlacklist();
- $ip = $_SERVER['REMOTE_ADDR'];
- // Vérifie si l'IP est déjà blacklistée
- $blacklisted = self::checkBlacklist($ip);
- // Ajoute une tentative
- self::addBlacklist($ip);
- // Filtre les tentatives récentes
- $recent_attempts = array_filter($attempts, function ($attempt) use ($ip, $now, $time_window) {
- return $attempt['ip'] === $ip && ($now - $attempt['timestamp']) <= $time_window;
- });
- // Si trop de tentatives, ajoute l'IP à la blacklist
- if (count($recent_attempts) + 1 > self::$max_attempts && !$blacklisted) {
- file_put_contents(self::$blacklist_file, "$ip\n", FILE_APPEND);
- $blacklisted = true;
- }
- // Redirection si blacklisté
- if ($blacklisted) {
- header("HTTP/1.1 403 Forbidden");
- header("Location: /noAccess.php");
- exit();
- } else {
- return ["error" => 404, "text" => "La page que vous cherchez n'existe pas."];
- }
- } else {
- return ["error" => 404, "text" => "La page que vous cherchez n'existe pas."];
- }
- }
- /**
- * Vérifie si l'utilisateur actuel est blacklisté.
- *
- * @return void
- */
- public static function itIs() {
- if (self::checkBlacklist($_SERVER['REMOTE_ADDR'])) {
- header("Location: /noAccess.php");
- exit();
- }
- return NULL;
- }
- }
|