sieci komputerowe, cisco, webmastering, php, css, xhtml, javascript, google, linux, windows server

Zabezpieczanie formularza przy użyciu tokenów

Kategorie: Webmastering PHP | 28 grudnia 2006 11:10 | Odsłon: 6024 | Komentarzy: 8 | Permalink

Często spotykanym problemem wśród właścicieli stron jest tzw. spamowanie formularzy - technika spamerów, którzy umieszczają swoje reklamy np. w komentarzach do bloga wykorzystując umieszczone na nim formularze.

Istnieje możliwość łatwego przeciwdziałania temu procederowi poprzez dołączenie do formularza mechanizmów tokena - obrazka z kodem, który należy przepisać do pola obok.

Implementację mechanizmu tokenów rozpoczniemy od utworzenia pliku tokens.txt zapisując w każdej linijce kody, które będą się pojawiały w tokenie. Możemy je utworzyć przy użyciu jakiegoś generatora lub po prostu ręcznie (wygenerowanie kilkunastu kodów "z palca" powinno na początek wystarczyć).

Mając już listę kodów, tworzymy skrypt PHP, który będzie tworzył obrazek oraz umieszczał na nim wybrany kod na podstawie przekazanego przez GET argumentu - w argumencie tym przekazujemy numer linijki z kodem. Numer ten jest losowany w pliku z formularzem.

Na początku pliku tokens.php pobieramy plik tokens.txt do tablicy i wybieramy z niej token na podstawie argumentu n przekazanego przez GET:

<? $tokens=file("tokens.txt"); $token=$tokens[$_GET["n"]];

W kolejnych linijkach tworzymy obrazek, alokujemy kolory, które będą używane dalej w skrypcie oraz wypełniajmy tło kolorem białym:

$i=imagecreate(100,40); // szerokosc, wysokosc wygenerowanego obrazka $white=imagecolorallocate($i,255,255,255); $black=imagecolorallocate($i,0,0,0); $gray=imagecolorallocate($i,150,150,150); imagefill($i,1,1,$white);

Aby obrazek nie był zbyt łatwo odczytywalny, rysujemy "szumy":

for($c=0;$c<300;$c ) { $los1=rand(0,$width); $los2=rand(0,$height); imageline($i,$los1,$los2,$los1,$los2,$gray); }

Wreszcie rysujemy napis (kod) na obrazku oraz zwracamy go do przeglądarki jako plik GIF:

imagestring($i,5,20,12,trim($token),$black); header("Content-type: image/gif"); imagegif($i); ?>

Teraz przechodzimy do pliku, w którym mamy nasz formularz aby umieścić w nim następujące linijki, odpowiedzialne za wyświetlenie obrazka tokenu oraz umieszczenie pola na jego wpisanie:

<? $tokensmax=sizeof(file("$app_dir/tokens.txt")); $tokenid=rand(0,$tokensmax); ?> <label for="token">Przepisz token:</label> <input type="text" class="text" name="token" id="token"/> <img src="token.php?n=<?=$tokenid?>" alt="Token" /> <input type="hidden" name="tokenid" value="<?=$tokenid?>" />

Pozostaje jeszcze dodanie mechanizmu sprawdzającego poprawność wpisanego tokenu do pliku, do którego jest wysyłany formularz i który zajmuje się sprawdzeniem jego danych:

$tokens=file("$tokens.txt"); $token=$tokens[$_POST["tokenid"]]; if(trim($token)==trim($_POST["token"])) { // token poprawny, tutaj mozna umiescic dalszy kod }

Dzięki powyższym zabiegom, możemy w łatwy sposób zapobieć spamowaniu przez nasze formularze. Nie jest to może metoda idealna, bowiem bardziej zaawansowane skrypty mogą próbować np. rozpoznawać znaki, jednakże dla większości spamerów jest to przeszkoda, która może ostudzić ich zapał bowiem nie każdemu spamerowi chce się sprawdzać na jakiej zasadzie działa każdy z tego typu skryptów.

Wpisy o podobnej tematyce

Tomasz Guzik

28 grudnia 2006 11:31
IMHO lepszym pomysłem byłoby utworzenie sesji i zapamiętanie poprawnego tokenu *po stronie serwera*. W aktualnej formie skryptu wystarczy by spamer skopiował zawartość pola _tokenid_ do _token_.

PS http://sam.zoy.org/pwntcha/

omg

28 grudnia 2006 11:55
Przydałoby się akceptowanie zamiast "0" "O" (i na odwrót), ponieważ często się ze sobą mylą. Tak jest na rapidshare.

ayeo

10 marca 2007 12:53
Cyfry moznaw ogole pominac. Niewiel to zmniejsza ilosc kombinacji. Nie rozumiem pomyslu z plikiem txt, ktory zawiera tokeny!! Nie mozna ich generowac in real time??

luktom

11 marca 2007 00:28
Kwestia jest taka, że te liczby trzeba gdzieś przechować pomiędzy wyświetleniem obrazka z kodem, a jego weryfikacją po wysłaniu formularza. Oczywiście można je generować real-time i np. wstawiać do bazy, jednak jest to rozwiązanie bardziej skomplikowane - mnie raczej chodziło o pokazanie jak można to zrobić najprościej.

sf

15 marca 2007 08:17
Przydałoby się obracanie jeszcze tekstu, albo wprowadzenie jakiegoś tła bo tak to łatwo złamać taki token.

<a href="http://sf.jogger.pl">php blog</a>

kl

19 maja 2007 18:29
IHMO lepszy i trudniejszy do obejścia jest Sblam (http://sblam.com)

crash2k

27 sierpnia 2007 17:21
jak juz robicie tekst i pokazujecie przykladowy kod to niech on dziala...

JEST
<?
$tokens=file("tokens.txt"); $token=$tokens[$_GET["n"]];
MA BYC
<?
$tokens=file("tokens.txt"); $token=$tokens[$_GET["n"]];
$width = 100;
$height = 40;

JEST
$i=imagecreate(100,40);
MA BYC
$i=imagecreate($width,$height);

JEST
for($c=0;$c<300;$c ) {
MA BYC
for($c=0;$c<300;$c++ ) {

prawko

10 listopada 2009 23:24
za s??abe te szumy, m??j ocr rozpoznaje tekst :(

Dodaj komentarz

Token

Statystyka
Ładowanie...