Home > Webmastering > CAPTCHA bez dręczenia użytkownika

CAPTCHA bez dręczenia użytkownika

CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) – rodzaj techniki stosowanej jako zabezpieczenie na stronach www, celem której jest dopuszczenie do przesłania danych tylko wypełnionych przez człowieka.

Źródło: http://pl.wikipedia.org/wiki/CAPTCHA

Zapewne nie raz spotkaliście się z kodami obrazkowymi które trudno było rozpoznać nawet człowiekowi. Widziałem już różne zabezpieczenia przeciw spam botom, mniej lub bardziej wymyślne, a nawet takie które spowodowały że sobie odpuściłem wysłanie formularza gdyż nie byłem w stanie ich pomyślnie przejść.

W tym wpisie pokaże Wam jak zrobić alternatywne metody weryfikacji człowieczeństwa bez denerwujących kodów obrazkowych czy innych mechanizmów utrudniających życie.

Być może to co opiszę ktoś już wynalazł i stosuje z powodzeniem, nie mniej, wymyśliłem to przy okazji jednego projektu gdzie po dziś dzień działa i spisuje się znakomicie – chyba że tą stronę omijają spam boty ;) .

Idea

Na czym polega ów metoda? Na dynamicznej zmianie formularza, przed jego wysłaniem. Kolejno, w skrypcie PHP obsługującym daną formę, sprawdzamy poprawność struktury.

Spam boty, przeczesując sieć, odczytują z kodu HTML dostępne pola i wysyłają żądanie POST do lokacji widniejącej w  parametrze action. Jeśli zmienimy formularz dynamicznie przy pomocy JavaScript’u, wtedy spam bot nie zobaczy tych zmian i wyśle pierwotną wersję – wyjątkiem było by tutaj gdyby bot działał jak przeglądarka i interpretował całą stronę, ale w to wątpię.

Praktyka

Jeśli powyższy opis nie jest zbyt jasny, to poniższy przykład rozwieje wszelkie wątpliwości.

Załóżmy że mamy prosty formularz z jednym polem tekstowym – na przykład do dodawania komentarzy na stronę.

<form id="form" action="form.php" method="post">
  <input type="text" name="comment">
  <input type="submit" name="submit" value="Wyślij">
</form>

Po wysłaniu takiej formy i zrzuceniu w PHP zawartości tablicy $_POST otrzymamy:

array(2) {
  ["comment"]=>
  string(14) "mój komentarz"
  ["submit"]=>
  string(7) "Wyślij"
}

I w ten sposób wyglądała by przesłana zawartość jeśli wysłał by ją spam bot. Teraz wprowadzimy kilka zmian, aby ta wysłana przez człowieka (tj. z tradycyjnej przeglądarki) różniła się od tej powyższej.

Skorzystam z biblioteki jQuery w celu łatwiejszego manipulowania elementami dokumentu HTML.

$(document).ready(function(){
  $('#form').append('<input type="hidden" name="key" value="234786">');
  $('#form input[name="submit"]').removeAttr('name');
});

Co zrobiłem? Tuż po załadowaniu całego dokumentu, dodałem nowe ukryte pole formularza o nazwie key i wartości 234786. Kolejno, usunąłem atrybut name z przycisku submit. Po takim zabiegu, skrypt PHP widzi nasz formularz w następujący sposób:

array(2) {
  ["comment"]=>
  string(14) "mój komentarz"
  ["key"]=>
  string(6) "234786"
}

Jak widać, nie występuje już w tablicy $_POST w ogóle przycisk submit, a dodatkowo doszło ukryte pole key.

Jeśli teraz wyczulimy skrypt przetwarzający formularz na te zmiany, możemy odróżnić bota od człowieka:

if (( ! isset($_POST['submit'])) && isset($_POST['key']) && ($_POST['key'] == '234786'))
{
  echo 'jesteś człowiekiem :]';
}
else
{
  echo 'jesteś spam botem :[';
}

Zabezpieczenia

Pokazane tutaj rozwiązanie, w postaci usunięcia atrybutu przycisku submit, oraz dodanie pola hidden są tylko przykładowe. Siła tego rozwiązania tkwi w unikalności metody, a tutaj mamy naprawdę spore pole do popisu.

Możemy dodawać i usuwać pola. Manipulować nazwą lub zawartością pól ukrytych, np.: jego wartość musi być sumą kontrolną z tego co wpisze użytkownik w innym polu (wymagane podpięcie się pod zdarzenie onSubmit w takim wypadku). Możemy dodać pole z nazwą przeglądarki, adresem IP i porównać w skrypcie PHP czy się zgadzają oba wpisy. Pole do popisu jest naprawdę ogromne – niech poniesie Was fantazja, grunt to dobrze namieszać :) .

Sam kod JavaScript warto umieścić w zewnętrznym pliku oraz potraktować narzędziem typu kompresor JS. To utrudni ew. rozgryzienie naszego przypadku.

Uwagi

Czy jest to rozwiązanie idealne? Oczywiście nie. Pierwsza wada to wymagana obsługa JavaScript u użytkownika. Druga to łatwość obejścia tego typu zabezpieczenia przez człowieka. I tutaj są dwa aspekty tej przypadłości.

Autor bota musiał by przejrzeć kod naszej strony i zorientować się co tam się dokładnie dzieje i zmodyfikować swój twór. Jeśli przyjmiemy że każdy webmaster zastosuje inny algorytm zabezpieczający, to mało komu będzie się chciało dostosowywać swojego szkodnika do każdej strony z osobna tylko po to by móc masowo spamować. Koszt tej operacji przewyższał by zyski z rozsyłanego spamu.

Czyli, zasadniczo da się prosto dojść do tego jak spreparować formularz (chociaż jeśli ktoś namiesza to wcale to takie łatwe być nie musi ;) ), jednak jest to z ekonomicznego punktu widzenia nieopłacalne dla spamera.

  1. YanPL
    9 kwietnia 2010 at 00:20 | #1

    dowolny spambot z interpretacją javaskryptu ominie to zabezpieczenie (o ile się jeszcze czegoś nie namiesza po drodze). celem CAPTCHA jest oddzielenie automatu od człowieka a tu mamy cały test robiony przez automat, zwany przeglądarką internetową. Wystarczy raz w przeglądarce wpisać wiadomość, potem kliknąć dodaj komentarz, a potem ustawić auto-odświeżanie i wiadomość doda się tyle razy ile właściciel przeglądarki sobie zażyczy.

    takiego generycznego spambota z przeglądarki można zrobić w FF przez greasemonkey; piszemy skrypt który po naczytaniu strony i przetworzeniu js na stronie wklei jakąś treść do ‘comment’ i wywoła ‘submit’a.

  2. 9 kwietnia 2010 at 00:58 | #2

    No jeśli spambot umie interpretować JS to masz rację, ale to musi być praktycznie przeglądarka. Nie znam się na rozwoju spambotów ;) jeśli takie stanowią obecnie większość to faktycznie metoda niezbyt udana.

    Z drugiej strony, jeśli słyszy się o wynajmowaniu taniej siły roboczej z krajów wschodu do wspomagania botnetów i omijania graficznych captcha to już trudno wymyślić coś co jest skuteczne :|

  3. YanPL
    10 kwietnia 2010 at 16:04 | #3

    Właśnie, trudno jest zrobić dobre CAPTHCHA. Metody oparte o losowe pytania na tak/nie są złe, bo bot ma 50% szans na trafienie, odczytywanie z obrazka jest złe bo często bardziej uciążliwe dla usera niż bota, a stosowanie tricków opartych o założenie że bot różni się od przeglądarki i usera w sposób technologiczny jest o tyle złe że założenie nie musi być spełnione.
    Automatyczna filtracja treści/ilości wiadomości też popełnia błędy, a ręczna filtracja jest niewygodna.

  4. 10 kwietnia 2010 at 17:24 | #4

    Wg. mnie dobre są działania matematyczne. Ogółem proste dla człowieka, i łatwiej je wykonać czasami niż się męczyć z odczytaniem obrazka. Np: dwa dodać osiem :) Najlepiej tekstem właśnie.

  1. Brak jeszcze trackbacków