Powrót na bloga
Podstawy Opublikowano 19.08.2026 6 min czytania

Co chroni formularz: CAPTCHA, honeypot, pułapka czasowa, token CSRF

Wiele formularzy kontaktowych opiera się na jednym triku przeciw spamowi, który często zatrzymuje tylko proste boty. Co daje każda warstwa ochrony, ile kosztuje i jakie połączenie ma sens.

Spamu przez formularze kontaktowe rzadko wysyła człowiek, który pisze ręcznie. Zwykle robi to oprogramowanie, które wyszukuje formularze, wypełnia każde pole i wysyła wynik – tysiące razy. Istnieje kilka zabezpieczeń, a każde działa w zupełnie innym miejscu. Gdy wiesz, co każde z nich naprawdę robi, unikniesz dwóch błędów: formularza bez realnej ochrony i formularza strzeżonego tak mocno, że prawdziwi ludzie rezygnują.

Warstwy ochrony w porównaniu
Warstwa i co zatrzymuje
  • Honeypot: proste boty, które wypełniają każde pole
  • Pułapka czasowa: skrypty wysyłające formularz od razu po załadowaniu
  • CAPTCHA: większość ogólnej automatyzacji
  • Token CSRF: żądania wysyłane prosto na endpoint
  • Limit zgłoszeń (rate limiting): zalew z jednego źródła
  • Proof-of-work: tanią masową wysyłkę, bez śledzenia i bez zagadek
  • Kontrole po stronie serwera: wszystko, co omija przeglądarkę
Czego nie łapie lub ile kosztuje
  • Celowane boty go pomijają; źle ukryty jest odczytywany przez czytniki ekranu
  • Boty, które czekają; bez podpisu po stronie serwera łatwo ją obejść
  • Przeszkoda dla wszystkich, bariery dostępności, często usługa zewnętrzna; istnieją serwisy rozwiązujące zagadki
  • Boty, które najpierw ładują stronę, też dostają ważny token
  • Spam rozłożony na wiele adresów IP
  • Zdeterminowany nadawca z mocą obliczeniową; wymaga JavaScriptu
  • Same nic – ale bez nich każda inna warstwa to dekoracja
Żadna warstwa nie pokrywa wszystkiego. Tanie, niewidoczne warstwy odsiewają masę; cięższe są na uporczywy, celowany spam.

Honeypot i pułapka czasowa: niewidoczne filtry

Honeypot to dodatkowe pole, którego ludzie nigdy nie widzą, np. pole o nazwie „website” ukryte za pomocą CSS. Proste boty wypełniają każde pole, więc wypełniony honeypot wskazuje na automat, a serwer może po cichu odrzucić wiadomość. Boty napisane specjalnie pod Twoją stronę albo renderujące ją jak przeglądarka go pomijają. Ukryj go porządnie: pole tylko przesunięte poza ekran może zostać odczytane przez czytnik ekranu, osiągnięte klawiszem Tab albo wypełnione przez autouzupełnianie. Użyj aria-hidden, tabindex -1 i autocomplete off oraz neutralnej etykiety, która prosi każdego, kto tam trafi, o pozostawienie pola pustego.

Pułapka czasowa zapamiętuje, kiedy formularz został wyświetlony, i odrzuca zgłoszenia, które przychodzą nieprawdopodobnie szybko. Człowiek potrzebuje kilku sekund na przeczytanie i wpisanie treści; wiele skryptów wysyła formularz w ułamku sekundy. Znacznik czasu trzeba sprawdzać na serwerze i chronić przed manipulacją, np. podpisać go albo trzymać w sesji – zwykłe ukryte pole z godziną bot po prostu nadpisze. Ustaw niski próg, bo z autouzupełnianiem prawdziwi ludzie też bywają szybcy. Boty, które po prostu poczekają, przejdą: pułapka czasowa to filtr, a nie mur.

CAPTCHA: skuteczna, ale nie za darmo

CAPTCHA wymaga dowodu, że to nie bot – od zagadek obrazkowych po kontrole działające w tle; popularne są m.in. reCAPTCHA, hCaptcha, Cloudflare Turnstile i Friendly Captcha. Zatrzymuje większość ogólnej automatyzacji i dlatego jest tak powszechna. Ale każda widoczna zagadka to przeszkoda, przy której część odwiedzających rezygnuje, a większość usług ładuje skrypt zewnętrznego dostawcy, co rodzi pytania o prywatność i zgody. Do tego CAPTCHA pomaga tylko wtedy, gdy jest poprawnie skonfigurowana: publiczny testowy klucz witryny, widżet bez swojego skryptu albo token, którego serwer nigdy nie weryfikuje, wygląda jak ochrona, ale nią nie jest. Darmowy test na formexposed.com wskazuje takie błędy z zewnątrz.

Częścią tego kosztu jest dostępność. Zagadki obrazkowe wykluczają osoby niewidome i wiele osób słabowidzących, alternatywy dźwiękowe nie pomogą osobom głuchoniewidomym, a podchwytliwe zadania logiczne obciążają osoby z niepełnosprawnościami poznawczymi. Kryterium sukcesu 1.1.1 WCAG 2.2 wymaga tekstu alternatywnego opisującego cel CAPTCHA oraz alternatywnych form angażujących inne zmysły. Kontrole w tle omijają większość tych problemów, ale gdy nabiorą podejrzeń, rozwiązaniem awaryjnym często znów jest zagadka wizualna – przetestuj tę ścieżkę klawiaturą i czytnikiem ekranu.

Token CSRF: ochrona przed fałszerstwem, nie przed spamem

Token CSRF to losowa wartość, którą serwer umieszcza w formularzu i oczekuje z powrotem. Powstał przeciw atakom cross-site request forgery, w których obca strona skłania przeglądarkę odwiedzającego do wysłania żądania, którego ten wcale nie zamierzał wysłać. W publicznym formularzu kontaktowym ma efekt uboczny: boty, które wysyłają dane prosto na adres formularza bez ładowania strony, zostają odrzucone. Każdy bot, który pobierze stronę i odeśle token, przejdzie. Większość frameworków i wtyczek do formularzy i tak ma tokeny CSRF – zostaw je włączone, ale nie traktuj ich jako ochrony przed spamem.

Co musi się dziać na serwerze

Kontrole tylko w przeglądarce niczego nie chronią
Wszystko, co działa wyłącznie w przeglądarce – walidację w JavaScripcie, skrypt sprawdzający honeypot, token CAPTCHA, którego nikt nie weryfikuje – można pominąć, wysyłając żądanie bezpośrednio. Każda decyzja o przyjęciu wiadomości należy do serwera.
  • Sprawdzaj ponownie każde pole na serwerze: pola wymagane, długość, format adresu e-mail i brak znaków nowej linii w polach, które trafiają do nagłówków maila.
  • Weryfikuj tokeny CAPTCHA i proof-of-work przy każdej wysyłce – u wystawcy albo we własnym kodzie – i odrzucaj tokeny użyte ponownie.
  • Ogranicz liczbę zgłoszeń na adres IP w danym oknie czasowym. To zatrzymuje zalew z jednego źródła; spam rozłożony na wiele adresów wymaga innych warstw.
  • Rozważ proof-of-work: przed wysłaniem przeglądarka rozwiązuje małe zadanie obliczeniowe. Odwiedzający nie widzą zagadki, nic nie jest śledzone, a masowa wysyłka staje się kosztowna.

Rozsądne połączenie: dwie albo trzy warstwy

  1. 1Zacznij od niewidocznych warstw: dostępnego honeypota i podpisanej pułapki czasowej, obu sprawdzanych na serwerze.
  2. 2Dodaj limit zgłoszeń na adres IP, żeby pojedyncze źródło nie mogło zalać formularza.
  3. 3Jeśli celowany spam nadal przechodzi, dołóż proof-of-work albo CAPTCHA – najlepiej bez widocznej zagadki i z dostępną alternatywą.
  4. 4Zostaw token CSRF, który zapewnia Twój framework – jako dodatek, a nie jako obronę.
  5. 5Przetestuj efekt jako odwiedzający – samą klawiaturą, z czytnikiem ekranu, na telefonie – i sprawdź, czy prawdziwe wiadomości nadal docierają.

Na wielu stronach honeypot, pułapka czasowa i limit zgłoszeń razem usuwają już większość ogólnego spamu, bez widocznej przeszkody; CAPTCHA to rezerwa na wypadek, gdy to nie wystarcza. Na WordPressie darmowa wtyczka formexposed łączy honeypot, kontrolę czasu i proof-of-work i nie potrzebuje Google. Co Twój formularz pokazuje z zewnątrz – jakie warstwy są obecne, czy CAPTCHA jest skutecznie skonfigurowana – sprawdzisz darmowym testem na formexposed.com: wystarczy domena, bez zakładania konta. Test nie widzi kodu na Twoim serwerze, więc część po stronie serwera pozostaje Twoim zadaniem.