Artykuły na każdy temat
[PHP] Zabezpieczenie typu antyflood (antiflood)
<?php
$config['antyflood']['time'] = 30;
// Tutaj wyimaginowane części kodu
if($_COOKIE['send_message']) // Dla rygorystycznych drani mamy oczywiście isset()
{
// Wiadomość do użytkownika, że musi troszeczkę poczekać
}
else
{
if($message -> send(/* jakieś parametry */)) // Imitacja wysyłania wiadomości
{
// Mówimy użytkownikowi, że wysłał wiadomość i częstujemy przeglądarkę ciasteczkiem
setcookie('send_message', 'bardzo_nieodpowiednia_treść', time() + $config['antyflood']['time']); // 30 sekund
}
else
{
// Mówimy użytkownikowi, że nie udało się wysłać wiadomości
}
}
?>
Niestety ta metoda jest zawodna, bo część przeglądarek nie akceptuje ciastek bądź użytkownik nie życzy sobie tego papu.
<?php
$config['antyflood']['time'] = 30;
session_start(); // Żelazna zasada pracy z sesjami
// Usuwamy, jeżeli jest taka potrzeba
if($_SESSION['send_message'] && (time() - $_SESSION['send_message']) > $config['antyflood']['time']) // Dla rygorystycznych draniu mamy oczywiście isset()
{
unset($_SESSION['send_message']);
}
// Tutaj wyimaginowane części kodu
if(!$_SESSION['send_message'])
{
if($message -> send(/* jakieś parametry */)) // Imitacja wysyłania wiadomości
{
// Mówimy użytkownikowi, że wysłał wiadomość i ładujemy informacje do sesji
$_SESSION['send_message'] = time();
}
else
{
// Mówimy użytkownikowi, że nie udało się wysłać wiadomości
}
}
else
{
// Wiadomość do użytkownika, że musi troszeczkę poczekać
}
?>
Problem polega na tym, że przeglądarka niekoniecznie musi zaakceptować ciastko z SID. W takim przypadku zostaje przekazywany w url'u, który tez nie musi zostać zaakceptowany to znaczy nie musi zostać przekazany identyfikator do kolejnej strony. W takim przypadku zabezpieczenie staje się całkowicie bezużyteczne.
<?php
$config['dir']['antyflood'] = './antyflood/';
$config['antyflood']['time'] = 30;
$ip = ip2long($_SERVER['REMOTE_ADDR']); // Jakaś metoda bądź funkcja do pobierania IP
$path = $config['dir']['antyflood'].$ip;
if(file_exists($path))
{
// Niekoniecznie trzeba usuwać, może wystarczyć update daty pliku (ale moim zdaniem lepiej usuwać)
if(time() - filemtime($path) > $config['antyflood']['time'])
{
unlink($path);
}
else
{
$catch = true;
}
}
if($catch)
{
// Wiadomość do użytkownika, że musi troszeczkę poczekać
}
else
{
if($message -> send(/* jakieś parametry */)) // Imitacja wysyłania wiadomości
{
// Mówimy użytkownikowi, że wysłał wiadomość i zapisujemy jego IP
touch($path); // Mogą być inne funkcje
}
else
{
// Mówimy użytkownikowi, że nie udało się wysłać wiadomości
}
}
?>
I teraz potrzebny worker, bo za każdym wywołaniem skryptu nie będziemy czyścić plików outdated. Najlepiej odpalić taki skrypt z poziomu CRON'a i nie martwic się, że folder z takimi danymi zostanie zasypany.
<?php
$config['dir']['antyflood'] = './antyflood/';
$config['antyflood']['time'] = 30;
$list = glob($config['dir']['antyflood'].'*');
if(!empty($list))
{
foreach($list as $file)
{
if(time() - filemtime($file) > $config['antyflood']['time'])
{
unlink($file);
}
}
}
?>
Cala sytuacja tyczy się gości, którzy nie maja możliwości rejestracji. Naturalnie rejestracja może ograniczać, ale co z multikontami? W takich wypadkach metoda IP konieczna. Oczywiście można stworzyć do tego klasę, ale to pozostawiam Waszej inwencji twórczej. Podsumowując powiem, że połączenie tych trzech metod może dać wymierne korzyści.
Komentarze
Dodaj komentarz
Rasmus