Jak zabezpieczyć formularz przed spamem w WordPress, Joomla!, PrestaShop, czy też innej, dowolnej aplikacji opartej o PHP? W ciągu kwartału zaledwie na kilku stronach o średniej oglądalności naliczyliśmy blisko 15 tysięcy spamerskich zgłoszeń z formularzy. Co zrobić, kiedy przez Twój formularz rejestrują się boty lub, po prostu, otrzymujesz za jego pomocą tony spamu?

Z tego artykułu dowiesz się:

  • jak zabezpieczyć formularz przed spamem?
  • jak chronić formularz przed botami i oszustami?
  • jak przygotować bezpieczny formularz, nie irytując użytkowników?

Zabezpieczamy formularz. Rozpoznanie popularnych zagrożeń w 2020 roku.

Na wstępie zastanówmy się, przed czym chcemy chronić formularz. Najczęściej zagadnienie ochrony formularza wiąże się z tym, co dany formularz wykonuje i jakie informacje przetwarza. Z mojego doświadczenia wynika, że chronimy się przede wszystkim przed dwoma rodzajami zagrożeń:

  1. Zagrożenia o charakterze typowo informatycznym
  2. Zagrożenia o charakterze merytorycznym.

Przeanalizowaliśmy wychwycone próby spamowania na naszych własnych stronach. Pod lupę wzięliśmy żądania wychwycone przez nas w poprzednim roku. Skala zagadnienia jest niemała. Najwięcej prób dotyczyło umieszczania spamerskich linków do swojej strony. Linki dotyczyły różnych branż i były w różnych językach.

SPAM porno – nic chyba zaskakującego, stanowił znaczną część żądań, zaraz po nim uplasował się SPAM medyczny, czyli oferty viagry, cialis, środków na łysienie itp. Finanse to przede wszystkim umieszczony przez boty spam, zawierający nigeryjski łańcuszek i „świetne” oferty inwestycyjne… I taka właśnie „rzeka” płynie przez nasz internet i dociera do formularzy na stronach. Dlatego potrzebujesz skutecznych zabezpieczeń.

Ochrona formularza przed zagrożeniami informatycznymi

Mówiąc o tym, jak zabezpieczyć formularz przed tego rodzaju zagrożeniami mam na myśli to, co wiąże się ze złymi intencjami atakującego, a co nie godzi bezpośrednio w merytoryczny sens formularza w sensie „oszustwa”. W tym obszarze nie mówimy zatem o prawidłowo wypełnionym wniosku kredytowym, w którym ktoś wpisał fałszywie wysokie zarobki.

Ochrona formularza przed zagrożeniami merytotycznymi

Kiedy dane są wprowadzone przez człowieka, ale w złej wierze, mówimy o tym, jak zabezpieczyć formularz przed atakami merytorycznymi. Chodzi mi tu o sytuacje, w której atakujący pragnie np. założyć sobie konto w naszym systemie. Robi to, aby skorzystać ze świadczenia do którego nie jest uprawniony etc. Często posługuje się fałszywymi danymi w celu zatarcia informacji o swojej tożsamości. Podaje zatem fałszywy adres e-mail, nieprawdziwe dane teleadresowe etc.

Zabezpieczenie formularza. Popularne typy ataków na formularz.

Spróbujmy dokonać przeglądu rodzajów zagrożeń, które czyhają na formularze na stronach www. Moim zdaniem najważniejsze z nich, to ataki:

  1. Spam przez formularz.
  2. XSS.
  3. SQL Injection.
  4. CSRF i flood fill.
  5. Brute force.

Zabezpieczenie formularza przed spamem – serio muszę o tym myśleć?

W skrócie: tak. Każdy formularz to potencjalny cel ataku. Dlaczego? Bo istnieje. Tyle wystarczy, więcej na ten temat znajdziesz we wpisie: Zautomatyzowane hakowanie stron – dlaczego dotyczy to także Ciebie?

Atak typu spam przez formularz zakłada, że dane wprowadzone do formularza są następnie gdziekolwiek wyświetlane. Ich celem samym w sobie nie jest zazwyczaj przełamanie zabezpieczeń. Zakładają natomiast, że po wypełnieniu formularza następuje:

  • wyświetlenie wprowadzonych informacji,
  • utrwalenie danych na stronie,
  • przesłanie ich do kogoś mailem,
  • zapisanie ich do bazy danych.

Bez względu na powyższe, atakujący liczy na to, że treść prędzej czy później będzie widoczna na stronie lub przeczytana. Istnieje prawdopodobieństwo, iż człowiek zapozna się z treścią (np. reklamą atrakcyjnych środków na potencję) albo kliknie w znajdujący się w treści link, co daje szeroki wachlarz możliwości dla atakującego.

Po co w ogóle boty atakują formularze?

Dla uzyskania linków, które zostaną rozpoznane przez roboty wyszukujące, a także – po prostu ludzie. To, co dzieje się dalej, zależy oczywiście od strony docelowej. Może to być przykładowo:

  • strona bazująca na phishingu (wyłudzające dane do logowania np. do banku),
  • spamerski link w nadziei na to, że znajdzie go robot indeksujący Google i tym samym atakujący pozyska link do siebie,
  • bezczelne przekierowanie na mniej lub bardziej legalną ofertę czegokolwiek (głównie: porno, finanse, środki na potencję),
  • malware, infekujący komputer użytkownika.

Tak czy inaczej, nie ma wątpliwości – spam jest niepożądany. Począwszy od popsucia Twojej pozycji strony w Google, nadmierny nakład pracy nad filtrowaniem informacji w Twojej bazie, aż po alerty antywirusów po wejściu na stronę i realną utratę środków finansowych. Brzmi jak niezła motywacja, żeby się o to zatroszczyć, prawda?

Zabezpieczamy formularz przed spamem i botami.

WAF – Web Application Firewall

Aby skutecznie chronić formularz proponuję podejście oparte o kilka linii obrony. Pierwszą linią jest filtrowanie ruchu w oparciu o „grube” zasady. Dobrze zatem skorzystać z hostingu oferującego ochronę WAF (Web Application Firewall). Żądania są filtrowane ZANIM zostaną one przeprocesowane przez Twoją aplikację. W ten sposób można ochronić się przed znaczną częścią masowych zagrożeń.

Tego typu mechanizmy bazują na sygnaturach ataków – np. w żądaniu występują określone, charakterystyczne cechy, dotyczące docelowego adresu url, adresu atakującego, metody albo zawartości określonych zmiennych, które dość jasno wskazują, że żądanie takie ma wrogi charakter.

Rozwiązaniem może być instalacja możliwie prostego skryptu, który wywołasz niejako w „nagłówku” strony, przed właściwym procesowaniem żądania. Możesz realizować takie filtrowanie ruchu w oparciu o dostępne skrypty, jednak zalecam tu zachowanie ostrożności – każdy skrypt wykonywany w Twojej przestrzeni na serwerze, jeśli sam miałby podatność, może stać się celem ataku.

Walidacja formularza wg geo IP

Bardzo grubą i jednocześnie bardzo skuteczną metodą filtrowania ruchu jest blokada na geograficzne pochodzenie ruchu. Możesz skorzystać z bezpłatnych baz geoIP i na podstawie adresu IP ustalisz jego źródło pochodzenia.

W wielu wypadkach interesować Cię będzie wyłącznie ruch z Polski, albo z UE. Możesz zatem do dalszego przetwarzania dopuszczać wyłącznie ruch spełniający kryterium geograficzne. Pamiętaj, że jest to opcja dość „mocna” – jeśli ktoś będzie chciał skorzystać z Twojego formularza z egzotycznych wakacji – nie uda mu się to!

Pamiętaj o aktualizacjach

Wdrażając ochronę formularza, bazującą na adresach IP, pamiętaj o regularnej aktualizacji baz. W przeciwnym razie, wraz z upływem czasu, skuteczność będzie maleć, a jednocześnie narazisz się na rosnącą liczbę incydentów fałszywie pozytywnych.

Walidacja formularza wg czarnej listy IP

O pewnych adresach IP możesz wiedzieć, że stanowią one raczej źródło „złego” ruchu. Należą do nich przede wszystkim te adresy, z których w ostatnim czasie dokonano nadużyć. Ruch z takich adresów warto jest po prostu blokować i nie przetwarzać danych z formularza, pochodzących z takich adresów IP.

Listy IP możesz budować samodzielnie lub opierać się o takie znalezione w sieci. Bardzo istotne, że muszą to być listy świeże. W wypadku zmiennych adresów IP dzisiaj może posługiwać się takim adresem atakujący, a jutro normalny użytkownik.

Filtrowanie wg adresów IP niesie za sobą jeszcze jeden istotny czynnik ryzyka. Chodzi o omyłkowe odfiltrowanie ruchu z robotów indeksujących, przede wszystkim Google Bot’a. Rozpoznawanie google botów to osobny temat, który zasługuje na kolejny wpis, nie będę go tu zatem rozwijał.

Captcha… czyli jak zabezpieczyć formularz przed robotem.

Część, czasem nawet znaczna część wypełnień formularza na Twojej stronie będzie odbywała się poprzez zautomatyzowane próby hackowania strony. Dobrze byłoby rozpoznać, czy po „drugiej stronie” znajduje się człowiek, czy atakującym jest po prostu robot.

Jedną z pierwszych historycznie prób był mechanizm captcha, który z pewnością kojarzysz – polegał na tym, że na koniec formularza (choć technicznie w dowolnym miejscu) – należało odpowiedzieć na pytanie o wynik jakiegoś działania matematycznego, dokończyć zdanie itp.

Z czasem te metody okazywały się zbyt mało skuteczne, spopularyzowało się przepisywania tekstu z obrazka. O ile człowiek nie miał problemów z odczytaniem liter, o tyle roboty nie radziły sobie dobrze… do czasu.

A co z doświadczeniem użytkownika?

Jakiekolwiek działania dodatkowe na formularzu, jak rozpoznawanie znaków drogowych, tygrysów, witryn sklepowych czy wodospadów, a także rozwiązywanie trudnych zadań z matmy – to wszystko realnie utrudnia użytkownikowi korzystanie z Twojego formularza, dlatego zdecydowanie doradzam Ci powstrzymanie się od takich metod. Moje doświadczenia wskazują, że formularz można zabezpieczyć z satysfakcjonującą skutecznością bez utrudniania życia użytkownikom.

Zabezpieczenie formularza przez Google reCaptcha

Swoistym przełomem okazało się podejście Google reCaptcha v2. Kto z nas nie klikał w obrazki z witrynami sklepowymi albo znakami drogowymi? Mechanizm ten był interesujący i adaptacyjny. Jeśli podejrzewał, że po drugiej stronie znajduje się robot, to skala zadań stopniowo rosła.

O ile skuteczność tego zabezpieczenia można ocenić dość dobrze, o tyle z pewnością wygoda użytkowników mocno na tym cierpiała. Bawiłeś się dobrze zaznaczając znaki? Nie znam nikogo, kto by to polubił. W Sieci można znaleźć zresztą informację, że w ten sposób pomagaliśmy Google w trenowaniu mechanizmów uczenia maszynowego używanych do autonomicznego samochodu.

Technologia ewoluuje i Google do naszej dyspozycji stawia Google reCaptcha v3. To całkowicie odmienny mechanizm, praktycznie przezroczysty dla zwykłego użytkownika. Google poprzez ten mechanizm i swoje metody analizuje zachowanie użytkownika na całej stronie i na tej podstawie nadaje użytkownikowi swoisty „rating” od 0 do 1.

Ocena 1 oznacza, że Google ma w zasadzie pewność, że po drugiej stronie jest człowiek, 0 oznacza, że jest to robot. W większości wypadków ludzie, po okresie „wytrenowania” mechanizmu, uzyskują noty rzędu 0,7 do 0,9. W praktyce jednak na stronie z ruchem rzędu 20k uu miesięcznie mimo kilku tygodni wciąż w wielu wypadkach zdarzało się, że ludzie uzyskiwali zaledwie 0.1 lub 0.3 pkt.

Google reCaptcha v.3 sama niczego nie blokuje.

Jako programista dostajesz informację o nadanym scoringu i to od Ciebie zależy, czy pozwolisz przetworzyć formularz, czy też nie. Ja osobiście z tego mechanizmu zrezygnowałem, w moich implementacjach zbyt często okazywało się, że normalny użytkownik uzyskiwał scoring 0.1 lub 0.3.

Jak zabezpieczyć formularz przez honeypot

Honeypot (ang. garnuszek z miodem) to po prostu przynęta, pułapka założona na roboty maszynowo wypełniające Twój formularz. Tego typu roboty zazwyczaj nie analizują dokładnie pól formularza, tylko starają się je wszystkie wypełnić losowymi niemal treściami.

Jeśli zatem przygotowalibyśmy pole, które jest widoczne dla robota, ale dla człowieka już niekoniecznie, to jest spora szansa, że robot je wypełni i w zasadzie zerowa, że zrobi to człowiek.

Honeypot jest zatem polem formularza, które przygotowujemy tak, aby człowiek nie mógł zobaczyć go w „ludzkiej” przeglądarce. Można to realizować w stylach css, poprzez umieszczenie takiego pola zdecydowanie poza polem widzenia człowieka. Przykładowe techniki, które możesz wykorzystać:

  • pole typu „hidden”,
  • właściwość css display: none,
  • właściwość css visibility: hidden,
  • bezwzględne pozycjonowanie css, np. przesunięcie w lewo o -2000px,
  • przezroczystość.

Autouzupełnianie - co może pójść nie tak?

Podczas stosowania pól typu honeypot zadbaj koniecznie o to, żeby nie były one wypełniane przez przeglądarkę automatycznie! W przeciwnym wypadku ludzie będą fałszywie „łapani” na Twój honeypot… a Ty nawet się nie zorientujesz, bo przecież pole nie jest widoczne. Ustawiamy zatem właściwość autocomplete pola formularza na off.

Po ustawieniu takiego pola pozostaje jeszcze odpowiedni warunek w kodzie, zakładający, że jeśli cokolwiek jest przekazane w zmiennej z nazwą pola przygotowanego jako honeypot – dalsze procesowanie formularza nie odbywa się. Dodatkowo proponuję w takim wypadku dodanie IP do czarnej listy.

Jak chronić formularz przed spamem w oparciu o CSRF?

CSRF – Cross Site Request Forgery oznacza fałszowanie żądania na innej stronie. Przetwarzanie formularza polega najczęściej na tym, że dane z niego są przesyłane metodą POST lub GET na adres skryptu, który może je przetworzyć, ale co do zasady – na tej samej stronie. Jeśli wysyłasz żądanie na inną stronę, a ona nie jest przed tym chroniona, to może „wykonać” takie żądanie, procesując dane tak, jakby pochodziły one od niej samej.

Ochrona przed żądaniami nie inicjowanymi przez użytkownika strony to ważny element bezpieczeństwa formularza. Tego typu zabezpieczenie oznacza, że formularz jest procesowany tylko wówczas, kiedy wiemy, że wypełnił go użytkownik strony.

Czasami jest to pożądana funkcjonalność i tak to sobie programista wymyślił. Jest to jednak, w mojej ocenie, bardzo ryzykowne, bo otwiera to drogę wszelkim robotom atakującym strony, ułatwiając im bardzo masowe wykonywanie ataków w oparciu o zestawy danych generowane masowo po swojej stronie i wysyłane raz za razem na stronę atakowaną.

W efekcie w ten sposób Twoja strona może na przykład zostać zasypana dziesiątkami fałszywych komentarzy pod postem, przesłanymi w ciągu minuty. Przy dużej intensywności mówimy wówczas o zjawisku flood fill, czyli masowego wypełniania formularza, co wygląda jak „powódź” zgłoszeń.

W tym celu najlepiej jest skorzystać z mechanizmu sesji. Użytkownik na stronie formularza, w swojej sesji, ma zmienną, nazwijmy ją $csrf, o wartości losowej. W formularzu dynamicznie generujemy pole typu hidden. o wartości równej tej zmiennej:

<? echo '<input name="zabezpieczenie" type="hidden" value="' . $csrf."> ;>

Rozpoczynając procesowanie formularza sprawdzamy, czy przekazuje on w ogóle wartość zmiennej stanowiącej zabezpieczenie oraz czy jest ona równa tej przechowywanej w sesji. Jeśli mówimy o normalnym zachowaniu użytkownika na stronie, to zawsze będzie ona równa, więc ryzyko false-positive jest zerowe.

Jeśli formularz spróbuje wypełnić bot, wrzucające quasi-losowe zawartości zmiennych przez POST lub GET na adres naszego formularza, to jego prymitywny mechanizm nie będzie znał prawidłowej wartości sesyjnej zmiennej $csrf. Co za tym idzie – takie żądanie powinno zostać odrzucone.

Jak zabezpieczyć formularz przed spamem? Analizujemy czas wypełniania.

Kolejną techniką, którą warto znać, jest ochrona bazująca na czasie wypełniania formularza. Zakłada ona, że użytkownik „ludzki” wypełnia formularz w czasie np. min. 2-3 sekund.

Tymczasem roboty atakujące formularze masowo próbują wypełniać formularz z ogromną częstotliwością, zazwyczaj są to dziesiątki lub setki formularzy na minutę.

Jeśli wiec czas wypełniania jest podejrzanie krótki, warto rozważyć odrzucenie tego rodzaju formularza. Zwróć jednak uwagę, że podczas korzystania z autouzupełniania czas może być faktycznie krótki, co prowadziłoby do zdarzenia typu false-positive.

Jak ustawić czas graniczny?

Nie ma jednej, złotej reguły, pozwalającej na stwierdzenie, jaki czas jest „dobry” jako kryterium. U mnie sprawdzały się czasu rzędu 1-2 sek. Z pewnością zależy to od złożoności samego formularza, liczy pól i skali trudności. Na czas wypełniania przez człowieka wpływa też to, ile pól skorzysta z autouzupełniania czy też UX samego formularza. Przed wdrożeniem ochrony możesz po prostu zapisywać, ile trwało wypełnianie formularza – będziesz wiedział dokładnie, ile to trwa w Twoim wypadku. Pomocne mogą okazać się też aplikacje do analizy zachowania użytkownika na stronie (np. HotJar, MouseFlow etc.)

Krok 3. Ochrona formularza w zależności od wprowadzonych informacji – walidacja zaawansowana. Przykłady.

Jak zabezpieczyć formularz przed spamem w obcym języku?

Dużo spamu jest w języku angielskim lub chińskim. Jeśli zawartość zmiennych zostanie zakwalifikowana do tego rodzaju języków, a nie zależy Ci np. na komentarzach na blogu w tym języku, możesz dość sprawnie zaimplementować wykrywanie języka i na tej podstawie podejmować decyzje o zatrzymaniu procesowania.

W tym zakresie polecam Twojej uwadze trzy podejścia, różniące się pracochłonnością, uniwersalnością i szybkością.

Po pierwsze: Możesz zbudować listę niedozwolonych słów typu „viaga” itp. Wówczas wszystkie zgłoszenia, zawierające dane słowo będą odrzucane.

Po drugie: Możesz zbudować listy bazujące na kodowaniu znaków, aby wykrywać znaki z innych alfabetów. Ja na przykład nie chciałem mieć na stronie chińskiego spamu. Problem tego spamu w formularzu rozwiązałem stosując wyrażenie regularne wykrywające znaki chińskie:

preg_match('/\p{Han}+/iU',$string);

Po trzecie: Możesz skorzystać z zaawansowanych metod uczenia maszynowego w celu rozpoznawania języka wprowadzanych informacji. Stosowane metody opierają się o częstotliwość słów charakterystycznych dla poszczególnych języków.

Istnieją gotowe biblioteki, które zwracają informację o języku na podstawie próbki tekstu i można z nich skorzystać także bezpłatnie.

Walidacja PESEL w formularzu

Jeśli w Twoim formularzu występuje numer PESEL. to możesz sprawdzać bardzo dokładnie, czy wszystko jest z nim w porządku. Zdecydowanie polecam Ci w tym wypadku lekturę wpisu o walidacji PESEL w PHP.

Proste sprawdzenie sumy kontrolnej algorytmem Luhna nie jest wystarczające. Znane są przypadki strat na setki tysięcy złotych z powodu skutecznych wyłudzeń, opartych o PESEL, który przeszedł walidację sumy kontrolnej. Jednocześnie był on całkowicie fałszywy.

W dużym skrócie polecam w tym wypadku sprawdzać:

  • sumę kontrolną PESEL,
  • wiek osoby, której PESEL dotyczy,
  • czy osoba taka się już urodziła,
  • czy osoba jest pełnoletnia,
  • czy płeć zgadza się z tą wynikającą z imienia.

Jak zabezpieczyć formularz? Prawidłowy adres e-mail.

Gorąco polecam Ci trójstopniową walidację email. W pierwszym kroku sprawdzamy czy adres ma poprawną składnię – czy zawiera małpę i domenę po niej.

W drugim kroku proponuję sprawdzić, czy dana domena, którą łatwo możesz „wyjąć” z adresu, posiada w ogóle rekordy MX. W ten sposób będziesz mógł odsiać adresy całkowicie zmyślone, w nieistniejących domenach, albo domenach bez skonfigurowanej obsługi poczty.

Wiarygodność email w zabezpieczeniu formularza przed spamem.

W trzecim kroku proponuję sprawdzenie adresu email pod kątem merytoryki, zarówno tego, co jest „przed małpą”, jak i „po małpie”. Chodzi o wychwycenie sytuacji, w których mamy do czynienia z adresem:

  • u tymczasowego operatora poczty,
  • u darmowego operatora poczty,
  • adresem zawierającym słowa budzące obawę co do rzetelności.

Poczta utrzymywana u operatora tymczasowego oznacza, że dana osoba nie planuje raczej czytać tego, co do niej prześlesz. Po prostu założyła sobie pocztę na chwilę, aby kliknąć w linka potwierdzającego lub aktywacyjnego. Istnieją setki popularnych domen operatorów tymczasowych. W naszych rozwiązaniach korzystam z tego typu list, pozwalają one na identyfikację zgłoszeń z formularza, które są „niskiej jakości”.

Poczta darmowa może nie oznaczać niczego złego, ale z drugiej strony – nie jest to tak samo wiarygodne konto, jak adres we własnej domenie. Z racji coraz większej popularności bezpłatnego gmaila i tysięcy skrzynek utrzymywanych przez onet czy wp, radzę nie odrzucać tego typu zestawu danych tylko na podstawie „darmowej” poczty. W niektórych zastosowaniach warto sobie taki zestaw danych „oflagować” do dalszego sprawdzenia.

Ostatnia porada dotyczy głównie popularnych marek. Jeśli adres zawiera np. nazwę banku, albo dużego operatora telekomunikacyjnego, firmy kurierskiej etc – to możesz przyjąć śmiało, że szansa, iż jest to prawdziwy adres jest niewielka. No chyba, że Twój formularz jest przeznaczony dla pracowników sektora bankowego albo firm kurierskich 😉 Warto przyglądać się bliżej mailom zawierającym takie nazwy marek. Przykład maila to support@paypal-support-center.com. Nie jest to oficjalna domena PayPala i „gołym okiem” widać, że właściciel adresu planuje podszywanie się pod PayPal.

Jak ochronić formularz – walidacja imienia i nazwiska

Walidacja imienia i nazwiska dla języka polskiego jest o tyle przyjemna, że istnieje prosta zasada z zaledwie kilkoma wyjątkami. Jeśli tylko Twój formularz jest przeznaczony dla Polaków, to śmiało możesz przyjąć, że imiona zakończone na „-a” są żeńskie, z uwzględnieniem zaledwie kilku wyjątków, jak „Kuba”. Metoda ta nie jest w 100% dokładna, bowiem zdarza się, że w Polsce użytkownik formularza może posługiwać się imieniem charakterystycznym dla odmiennej płci. Przykładowo popularny niegdyś polityk – Jan Maria Rokita, mógłby nie przejść tego rodzaju walidacji.

Tego typu sprawdzenie, w połączeniu z numerem PESEL, może jednak dać Ci już pewną wskazówkę co do tego, czy zestaw danych jest wiarygodny.

Jak zabezpieczyć formularz? Walidacja adresu.

Ostatnim zagadnieniem, którym chciałem się z Tobą podzielić, jest walidacja adresu. Zakładam, że zależy Ci na adresie w Polsce. To, co może Ci pomóc uzyskać lepszej jakości dane, to na pewno dobra walidacja kodu pocztowego. Oczywiście jego składnia to dwie cyfry, myślnik, trzy cyfry.

W Sieci znajdziesz też bez problemu listę miejscowości, możesz więc sprawdzić, czy podana miejscowość istnieje. Wyobrażalne jest też oczywiście łączenie kodu pocztowego z miejscowością, a nawet ulicy z miejscowością, aby sprawdzić, czy w danej miejscowości istnieje w ogóle dana ulica.

Metody te wydają się dawać obiecująco dokładną weryfikację, jednak osobiście z nich nie korzystam, ponieważ wprowadzają one dwie komplikacje:

  1. Są słabo odporne na literówki w nazwach ulic
  2. Wymagają stałego aktualizowania Twojej bazy wiedzy o ulicach, kodach, miejscowościach itp.

Listy adresów IP a ochrona przed botami i spamem.

Być może zechcesz prowadzić listę z ostatnimi adresami IP z których wysyłano dane do formularza). Daje Ci to kolejne możliwości ochrony. Dla dodatkowej ochrony danych wystarczy zapisać hash adresu, nie musi to być adres jawny. Możesz taką listę „rotować”. Wówczas w pierwszym kroku sprawdzisz, czy adres IP, z którego przychodzi żądanie, nie jest już na takiej liście.

Lista przydaje się także do blokowania ataków typu brute-force i flood-fill, jeśli zauważysz, że z danego adresu IP w ciągu krótkiego czasu dochodzi do wielokrotnego przesłania formularza – z wysokim prawdopodobieństwem możesz założyć, że takie IP powinno trafić na czarną listę.

Możesz też pokusić się o blokowanie i wpisywanie na czarną listę adresów IP w razie wykrycia żądania, zawierającego inne rodzaje zagrożeń. Przykładem mogą być żądania zawierające próby SQL Injection albo XSS, czyli próby wstrzyknięcia kodu manipulącego bazą lub umieszczającego/wykonującego niepożądany skrypt.

Jeśli chcesz stworzyć „lekkie” rozwiązanie, to możesz poradzić sobie z tym zadaniem nawet bez danych. Listy IP można przechowywać w pliku tymczasowym. Przyda Ci się wówczas Ci się funkcje PHP. Być może przydadzą Ci się takie funkcje, jak json_encode() lub serialize() – przy ich pomocy przekształcisz tablicę adresami IP i oznaczeniami czasu na jedną zmienną tekstową. Możesz ją zapisywać i odczytywać funkcjami file_put_contents() i file_get_contents().

Przy większym ruchu prawdopodobnie lepszym pomysłem będzie skorzystanie z bazy danych.

Jak zatem chronić formularz przed botami? Indywidualnym podejściem!

Ostatnim zadaniem, które warto wykonać, jest określenie polityki postępowania w razie złamania określonej reguły. Niektóre wymagają tylko powiadomienia użytkownika (np. „Prawdopodobnie popełniłeś błąd w PESEL – nie zgadza się suma kontrolna”). Inne powinny skutkować zablokowanie żądania w ogóle (np. próba podania PESEL osoby nieżyjącej albo jeszcze nieurodzonej). Kolejne wręcz proszą się o dodanie IP użytkownika do czarnej listy.

Fakt, że niektóre elementy w moim wypadku nie sprawdziły się dobrze, wcale nie znaczy, że nie warto spróbować u siebie. Zachęcam Cię do rozpoczęcia myślenia o ochronie Twojego formularza przed spamem od przemyślenia, jak powinna wyglądać Twoja polityka ochrony przed spamem i botami.

Jak skutecznie zabezpieczyć formularz? Podsumowanie.

Kiedy wdrożysz opisane tu techniki – przekonasz się, że spam przez formularz stanie się tylko bladym wspomnieniem. Oczywiście żadna metoda nie daje 100% gwarancji. Tym niemniej – opisane przeze mnie kroki na wielu stronach pozwoliły mi ograniczyć ilość spamu z formularza o dobre 90-99%.

Po wdrożeniu w/w metod z tysięcy spamerskich wpisów wykonanych przez boty atakujące formularz miesięcznie uzyskałem redukcję do maksymalnie kilku miesięcznie.

A Ty? Jakie masz doświadczenia ze spamem o formularzami wypełnianymi przez boty? Zapraszam do dyskusji w komentarzach i dzielenia się wpisem w mediach społecznościowych.

Artur Pajkert z kubkiem cyber_Folks
>
Artur Pajkert
Od 18 lat dzieli się wiedzą i poradami w sprawach e-marketingu i hostingu, jako menedżer, autor publikacji, prelegent, bloger, wykładowca akademicki.

31 odpowiedzi do "Jak zabezpieczyć formularz przed spamem w 2020?"

  1. Zgred pisze:

    Do wordpressów można zainstalowac wtyczkę:Akismet i wtedy do WP Contact Form (jeśli ktoś tego używa) powstawiać zmienne, które filtruja spam. Dało mi to 99% ochronę.

  2. Roman pisze:

    Dzięki za publikację. Niestety często mamy takie problemy, że dostajemy właśnie SPAM. Wdrożenie reCaptcha v.3 niestety spowalnia stronę … Czy masz jakiś konkretny przykład jak prosto można to wykonać dla najprostszej strony dla WordPress ?

  3. Zgred pisze:

    Masz powyżej to co napisałem. mam to u Siebie 🙂

  4. Artur Pajkert pisze:

    To, co Zgred mówi – dobrze mówi, ta wtyczka jest dość skuteczna. Pomocne może też być gotowe rozwiązanie z honeypotem do Contact Form 7: https://pl.wordpress.org/plugins/contact-form-7-honeypot/

    1. Arturze blokujesz chińskie spamy poprzez
      preg_match(’/\p{Han}+/iU’,$string);
      a jakby to wyglądało z językiem rosyjskim. U mnie spam to głównie cyrylica.

      1. Artur Pajkert pisze:

        Cześć, https://www.regular-expressions.info/unicode.html – tu i jeszcze tu: https://stackoverflow.com/questions/5510439/regular-expression-for-validating-cyrillic
        znajdziesz nieco więcej inspiracji w tej kwestii. Można wyszukać praktycznie wszystkie „nietypowe” alfabety w ten sposób. Powodzenia!

        1. Ania pisze:

          U siebie na blogu używam wtyczki Akismet do walki ze spamem.
          Jaką wtyczkę polecasz do unowocześnienia komentarzy. Mam na myśli możliwość dodawania zdjęć w komentarzach. Szukam wtyczki darmowej lub za niewielkie pieniądze 🙂

  5. Mateusz pisze:

    Honeypot to ciekawe rozwiązanie. U siebie stosuję token CSRF i sprawdzanie czy formularz wysłany jest z tej samej domeny. reCaptcha v.3 za bardzo spowalnia stronę ;/

  6. Tomasz pisze:

    Dokładnie, ja używam na swojej stronie tej wtyczki co podał Artur i spełnia swoją rolę. Często zdarza się, że ktoś wykryje to ukryte pole i przestawi swojego bota, wtedy zmieniam nazwy pól dla tego ukrytego pola i dokładam jeszcze jedno. Ważne, aby te pola nazywać typu telefon, email itp.

  7. oliwka24 pisze:

    Dla WordPress’a wtyczka „Simple Google reCAPTCHA” powinna załatwić sprawę. Przynajmniej u nas zablokowaliśmy całkowicie masę spamu. Niektóre plugin-y bezpieczeństwa pod WP posiadają moduły antyspamowe, ale tego nie testowaliśmy.

  8. CzłowiekSen pisze:

    Dobra sprawa z tymi zabezpieczeniami. Zawsze zastanawiałem się jak pozbyć się ilości spamu jakie do mnie wpływa z tego formularza. Teraz już wiem, głównie za sprawą komentarzy, które rewelacyjnie pokazały sposoby zabezpieczenia formularza. Wielkie dzięki!

  9. Biz pisze:

    A jakaś alternatywa dla Akismeta działająca na stronie na zwykłym szablonie html?

    1. Artur Pajkert pisze:

      Większość gotowców działa raczej pod konkretne systemy, najczęściej WordPress albo Joomla!. Daje się jednak okodować także czysty HTML dostępnymi rozwiązaniami, np. wykorzystać Google reCaptcha, tylko tyle, że to już przestanie być szablonem HTML – bez kodowania w PHP się raczej nie obejdzie.

  10. Maciej pisze:

    Artur, Honeypot i owszem daje rade. Dodatkowym wsparciem może być All In One WP Security & Firewall, która odfiltruje adresy IP i lokalizację geograficzną. Zawsze to większa ochrona

  11. Front pisze:

    Przy prostych autorskich rozwiązaniach sprawdzać się będzie połączenia dwóch sposobów jednocześnie. Nie jest zwolennikiem captchy. Ja sam osobiście na swojej stronie używam garnuszka i nieźle się to sprawdza. Nie eliminuje to całkowicie spamu, ale sporą część wyklucza. Większość spamu to wiadomości obcojęzyczne i myślałem nad wprowadzeniem jakiegoś prostego mechanizmu rozpoznawania języka (np. lista popularnych słów używanych w spamie)

    1. Artur Pajkert pisze:

      Dzięki za Twoją opinię. Słowa to moim zdaniem są ok, jeśli chcesz wychwycić dla danego alfabetu konkretne języki. Napisałem trochę regułem do WAF’a w oparciu o takie podejście i nieźle filtrowało spam medyczny, finansowy, porno itp. Dla filtrowania całymi alfabetami polecam jednak preg_matche z użyciem odpowiednich zakresów znaków, pięknie blokuje np. cyrylicę, chiński, japoński itp.

  12. Maxx pisze:

    Może filtrowanie wiadomości zawierających w treści link (z przedrostkiem http, www), lub kierujący na niepolską domenę..

    1. Artur Pajkert pisze:

      To jeden ze sposobów. Faktycznie, w moich metodach także wycinałem ruch z linkami – skutecznie odcina znaczną część spamu. Oczywiście jest efekt uboczny – niektóre komentarze zawierające „legalne” linki także będą zablokowane – coś za coś.

      1. Maxx pisze:

        W przypadku sklepów z zapytaniem o produkt link raczej nie powinien się pojawić. Co innego w usługach seo.

    2. Piotr pisze:

      Dokładnie jak napisał Artur. Jeśli klient dodaje w formularzu plik do pobrania z serwisu do przechowywania plików (np. Wetransfer lub dysk Google) to byłby klops.
      Z drugiej strony można do formularza dodać skrypt js taki, że jeśli w textarea wykryje link (http lub https) to pokazuje się informacja, żeby go usunąć z treści wiadomości

  13. Matt pisze:

    U mnie pomogło ustalenie dodatkowego pola typu hidden i licznika sekund w JS. Jeśli licznik nie zdąży doliczyć do np. 4s to znaczy, że leci bot i formularz jest blokowany.

    1. Artur Pajkert pisze:

      Czas wypełniania to moim zdaniem jedna z ciekawszych form walidacji. U siebie ustawiałem zazwyczaj 2 sekundy, ale 4s też spoko. Fajnie, że Ci ta metoda zadziałała.

  14. Anna pisze:

    Super artykuł! Chciałabym przetestować ten licznik sekund w JS, natomiast, czy mogłabym dopytać, jak konkretnie go ustawić? Jaki konkretnie kod należy wdrożyć? Będę bardzo wdzięczna za pomoc! 🙂

    1. Artur Pajkert pisze:

      Anno, ja to implementowałem na etapie PHP. W PHP w sesji zachowywałem timestamp momentu pojawienia się formularza i porównywałem go z timestampem z momentu utrzymania zestawu danych POST, kiedy formularz był wypełniony. Czyli $_SESSION[’timeRendered’]=time(); w chwili wyrenderowania formularza jeśli jest on „pusty” i potem $roznica = time() – $_SESSION[’timeRendered’]; kiedy strona jest renderowana z niepustym żądaniem $_POST. Kiedy $roznica<=3 to przerywałem przetwarzanie z komunikatem błędu dla użytkownika. W ten sposób metoda powinna działać także na roboty próbujące maszynowo wrzucić Ci coś przez tablicę POST, z pominięciem javasriptu.

  15. Marusz1976 pisze:

    Ja stosowałem wiele rozwiązań najlepszym dla mnie jest zastosowanie reCAPTCHA v3.

  16. Jola pisze:

    Nie Jooma! tylko Joomla!

    1. Artur Pajkert pisze:

      Słusznie – dzięki za wychwycenie literówki!

  17. Dżyszla pisze:

    Uwaga odnośnie WAF – please, dajcie ostrzeżenie, że włączanie wyłącza dyrektywę auto_prepand_file! Albo najlepiej opiszcie jakąś prostą instrukcję, jak zrobić to ręcznie w takim przypadku. I niech włączenie nie wyłącza wszystkich pozostałych ustawień w .htaccess, bo się srodze zdziwić można po włączeniu WAFa.

    1. Artur Pajkert pisze:

      Dzięki za komentarz, sprawdzimy, jak zrobić to lepiej.

  18. Wojciech pisze:

    Objaśnienia bardzo trafne i istotne. Choć przydał by się przykład prostego kodu do użycia na stronie.

  19. Plant Deco pisze:

    Bardzo ciekawy artykuł. Na pewno przyda mi się przy tworzeniu formularza na moją stronę internetową.

Dodaj komentarz

Twój adres e-mail nie będzie opublikowany.

Polecane dla Ciebie

Szukasz dalej?