Aller au contenu

Besoin d'avis d'experts


ZeBrian

Sujets conseillés

Bonjour,

Dans le cadre de la programmation d'un forum, se pose à moi le problème du flood : en effet, j'aimerais empêcher les petits hackers de faire trop de requêtes à la fois, et ce sans utiliser MySQL dans mon script antiflood puisqu'un serveur MySQL est vite saturé :whistling:

J'aimerais donc votre avis sur un petit script que j'ai écrit : y a-t-il des failles possibles, si oui lesquelles, et quels seraient les éléments à améliorer pour m'en sortir sans base MySQL ?

Le principe est simple : à partir des variables $intervalle et $max_acces, le script empêche un visiteur de charger plus de $max_acces fois une page pendant $intervalle secondes.

Voici donc le code !

<?php

$intervalle = 3;
$max_acces = 10;

if (!file_exists('cache'))
$cache = '';
else
$cache = file_get_contents('cache');

$good = false;
$current = time();
$temp = $cache;
while (true) {
$pos = strrpos($temp, "\n");
$time = substr($temp, $pos + 1, 10);
if ($time < $current - $intervalle)
break;
$temp = substr($temp, 0, $pos);
}
$last = substr($cache, $pos)."\n";

$f = fopen('cache', 'w');
fputs($f, $last.$current.' '.str_replace("\n", null, $_SERVER['REMOTE_ADDR']));
fclose($f);

str_replace(' '.$_SERVER['REMOTE_ADDR']."\n", null, $last, &$nb);
if ($nb > $max_acces)
die('Trop d\'accès en peu de temps ! Seriez-vous un méchant ? Ou pire ? Une méchante ???');

/*

A partir d'ici, on écrit le reste du code (ou bien sûr, on utilise un include)

*/

?>

Auriez-vous des conseils à me donner pour améliorer le script ? Peut-être que je ne devrais surtout pas faire comme cela, qui sait :unsure:

Bonne soirée et merci d'avance !

EDIT : Voir plus bas (post #3) pour la nouvelle version

Modifié par ZeBrian
Lien vers le commentaire
Partager sur d’autres sites

Je pense que ça serait même plus gourmand qu'une base MySQL.

En effet, dans une base, tu effectueras des recherches sur des données indexées, alors que sur un fichier texte, tu effectueras ces mêmes recherches dans un seul fichier, qui atteindra bien vite la centaine de méga-octets.

De plus, si j'ai bien compris ton script, tu ne lis que la dernière ligne du fichier, qui ne contient pas forcément l'adresse IP de la personne en question, d'où un très grand risque d'empêcher tout le monde d'accéder à ton site.

Par ailleurs, si ton temps entre chaque page est défini trop long, tu risques d'ennuyer tes utilisateurs légitimes, qui peuvent être rapides.

Si tu veux limiter les accès à ta base, tu peux éventuellement envisager une solution de cache de tes pages.

Lien vers le commentaire
Partager sur d’autres sites

Non, je ne lis pas que la dernière ligne bien sûr ! En fait je lis toutes les lignes qui ont été écrites moins de $intervalle secondes auparavant...

Et étant donné que le fichier ne dépassera que rarement les 20 lignes (il est convenablement vidé à chaque fois), je ne pense pas qu'il soit trop long à exécuter ! Je vais faire un petit bench pour tester :)

EDIT : Après quelques benchs, j'ai fait une nouvelle version un peu plus "intelligente" dirons-nous, qui parse beaucoup moins de chaînes que la précédente et se révèle donc plus rapide. Lors de plus d'une centaine d'accès en moins d'une seconde, le calcul reste de l'ordre de 0.5 à 1 millisecondes sur un serveur mutualisé de 1&1 :)

$intervalle = 3;
$max_acces = 10;

if (!file_exists('cache'))
$cache = '';
else {
$cache = false;
while ($cache === false)
$cache = _AT_file_get_contents('cache');
}

$good = false;
$current = time();
for ($i = $intervalle; $i >= 0; $i--) {
$pos = strpos($cache, "\n".($current - $i).' ');
if ($pos !== false) {
$good = true;
$last = substr($cache, $pos);
break;
}
}
if (!$good)
$last = '';

$f = false;
while ($f === false)
$f = _AT_fopen('cache', 'w');

fputs($f, $last."\n".$current.' '.str_replace("\n", null, $_SERVER['REMOTE_ADDR']));
fclose($f);

str_replace(' '.$_SERVER['REMOTE_ADDR']."\n", null, $last, &$nb);
if ($nb > $max_acces)
die('Trop d\'accès en peu de temps ! Seriez-vous un méchant ? Ou pire ? Une méchante ???');

Modifié par ZeBrian
Lien vers le commentaire
Partager sur d’autres sites

Veuillez vous connecter pour commenter

Vous pourrez laisser un commentaire après vous êtes connecté.



Connectez-vous maintenant
×
×
  • Créer...