Zapobiegaj spamowi formularzy kontaktowych php

Jestem amatorskim projektantem stron internetowych, szukałem na stackoverflow.com i innych stron internetowych i znalazłem wiele poprawek dla tego problemu mam, ale żaden z nich nie działa(prawdopodobnie dlatego, że wdrażam je nieprawidłowo). Mam nadzieję, że ktoś z większą wiedzą pomoże mi z prostą poprawką lub pokaże mi, jak zaimplementować jedną z poprawek, które znalazłem.

Problem: Mam bardzo prosty formularz kontaktowy php na stronie mojej firmy. Działa świetnie od lat, ale w w zeszłym tygodniu został zhakowany. Otrzymuję teraz setki zgłoszeń formularzy kontaktowych dziennie bez komentarzy, mają tylko (najwyraźniej poprawne) adresy e-mail i ciąg znaków w polu Nazwa (jak "58ee8b52eef46").

Próbowałem kilku technik, aby zapobiec temu spamowi, a one albo łamią mój formularz php, albo nie zapobiegają spamowi. Jeśli to możliwe, chciałbym rozwiązanie, które nie wymaga captcha zniekształcony test tekstu, i nie wymaga wszystkich pól formularza, aby być wypełniony.

Oto mój pełny kod PHP:

<?php
if(isset($_POST['email'])) {
  $email_to = "[email protected]";
  $email_subject = "website form submission";

  function died($error) {
    echo "We are very sorry, but there were error(s) found with the form you submitted. ";
    echo "These errors appear below.<br /><br />";
    echo $error."<br /><br />";
    echo "Please go back and fix these errors.<br /><br />";
    die();
  }

  if (!isset($_POST['name']) ||
    !isset($_POST['email']) ||
    !isset($_POST['telephone']) ||
    !isset($_POST['comments'])) {
    died('We are sorry, but there appears to be a problem with the form you submitted.');       
  }

  $name = $_POST['name'];
  $email_from = $_POST['email'];
  $telephone = $_POST['telephone'];
  $comments = $_POST['comments'];

  $error_message = "";
  if(strlen($error_message) > 0) {
    died($error_message);
  }
  $email_message = "Form details below.\n\n";

  function clean_string($string) {
    $bad = array("content-type","bcc:","to:","cc:","href");
    return str_replace($bad,"",$string);
  }

  $email_message .= "Name: ".clean_string($name)."\n";
  $email_message .= "Email: ".clean_string($email_from)."\n";
  $email_message .= "Telephone: ".clean_string($telephone)."\n";
  $email_message .= "Comments: ".clean_string($comments)."\n";

  $headers = 'From: '.$email_from."\r\n" .
             'Reply-To: '.$email_from."\r\n" .
             'X-Mailer: PHP/' . phpversion();
  @mail($email_to, $email_subject, $email_message, $headers);  
?>

Thank you for contacting us. We will be in touch with you soon. You will now be redirected back to example.com.
<META http-equiv="refresh" content="2;URL=http://www.example.com">

<?php
}
die();
?>
Author: Sl4rtib4rtf4st, 2017-04-12

7 answers

Prostą sztuczką jest utworzenie pola honeypot:

Html

<!-- within your existing form add this field -->
<input type="text" id="website" name="website"/>

Css

/*in your css hide the field so real users cant fill it in*/
form #website{ display:none; }

Php

//in your php ignore any submissions that inlcude this field
if(!empty($_POST['website'])) die();
 57
Author: Steve,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-26 11:54:53

[1]}jeszcze prostsze podejście, które działa dla mnie. Dosłownie każdy spam, który otrzymuję (d), miał adres url w wiadomości. Więc filtruję to i od tego czasu nie otrzymałem żadnych wiadomości spamowych. Kiedyś dostawałem około 10 tygodniowo.

Dodaj to pod Twoją linią $error_message =""; w Twoim pliku php:

if(preg_match('/http|www/i',$comments)) {
    $error_message .= "We do not allow a url in the comment.<br />";
  }

/i w preg_match sprawia, że sprawa jest niezależna. "Http" filtruje również dla "https".

 20
Author: Joseph K,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-07-26 11:09:16

Zazwyczaj boty przesyłają formularz bardzo szybko. Na tej podstawie innym rozwiązaniem może być dodanie kolejnego ukrytego pola, które zawiera liczbę sekund, które upłynęły od momentu otwarcia strony. Można to zrobić za pomocą JavaScript. Następnie sprawdź to w PHP. Jeśli liczba sekund jest mniejsza niż 5 sekund, to jest to spam (bardziej prawdopodobne, że prawdziwy klient potrzebuje więcej czasu, aby dopasować formularz). Liczbę sekund można dostosować na podstawie liczby pól, które zawiera formularz.

 4
Author: Alexandru Burca,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-22 09:48:08

Ukryte pola, głupie pytania (co to jest 3+4?), itp. nie są zbyt skuteczne w blokowaniu spamu na formularzach.

Zbadałem to kilka lat temu i wymyśliłem rozwiązanie, które nazywam "FormSpammerTrap". Używa kodu JavaScript do "oglądania" dla focus/onclick na wymagane pola. Zautomatyzowane procesy, o ile nie są wysoce dostosowane do konkretnej witryny (co zajmuje więcej czasu niż właściciele spambotów chcą wziąć), nie mogą "focus/onclick" wymaganego pola.

Mam darmowe rozwiązanie na moim www.FormSpammerTrap.com miejsce. I jest tam formularz, że spamowanie może próbować spamować...i od ponad 3 lat tak nie było. Zapraszamy do wypróbowania out...it to wszystko open source, więc możesz zobaczyć, jak to działa. (A jeśli korzystasz z formularza, nie pobieram twojego maila. Odpowiadam raz, a następnie usuwam twój e-mail.)

Moja technika jest znacznie bardziej skuteczna w blokowaniu spamów. Nie udało im się spamować formularza kontaktowego na tej stronie.

 3
Author: Rick Hellewell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-25 02:27:15

Utwórz pole formularza i ukryj je dla użytkowników. W skrypcie php sprawdź, czy to pole jest przesłane, ale puste. Teraz wiesz, że żądanie pochodzi z twojego formularza i użytkownika.

Spam wypełni ukryte pole, lub jeśli użyją twojego skryptu php direct, pole ochrony przed spamem nie jest ustawione.

HTML

<input name="website" type="text" class="website"/>

CSS

form .website{ display:none; } /* hide because is spam protection */

PHP

# spam protection
if (isset($_POST["website"]) && $_POST["website"] == "") {
  # your php code to mail here
} else {
  http_response_code(400);
  exit;
}

Możesz znaleźć więcej metod ochrony spamu formularza php tutaj: https://zinoui.com/blog/protect-web-forms-from-spam

 2
Author: BenRoe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-29 10:24:36

Jeśli spam, który dostajesz nie ma komentarza, dlaczego po prostu nie dodać czeku na to? Nie ma absolutnie żadnego powodu, aby prawdziwy, ludzki gość przesłał formularz kontaktowy Bez komentarza.

Ponieważ nie chcesz dodawać captcha, najprostszym rozwiązaniem w krótkim czasie byłoby sprawdzenie, czy komentarz ma minimalną liczbę znaków i zawiera co najmniej określoną liczbę słów.

Na przykład:

$comments = trim($_POST['comments']); // trim() to strip off whitespace from beginning and end, like spaces and linebreaks

if (strlen($comments) < 20 || substr_count($comments, " ") < 3) {
    died('Your comment is too short.');
}

Jest to bardzo proste sprawdzenie, czy komentarz zawiera co najmniej 20 znaków i co najmniej 3 spacje (4 słowa). Dostosuj w razie potrzeby.

 0
Author: rickdenhaan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-12 20:42:33

Mam inną metodę, którą z powodzeniem stosowałem na kilku stronach internetowych od ponad dziesięciu lat, bez ani jednego udanego ataku robotów spamowych. Wiem z dzienników serwera, że formularze są spamowane setki razy dziennie, ale nic z tego nie dotarło do mnie. Ta metoda nie wymaga Captcha ani żadnego innego zakupionego oprogramowania. Postaram się nie podawać tu wszystkich szczegółów, ale powiem tyle, że większość ludzi może to wdrożyć. Po pierwsze, będziesz potrzebował prostej grafiki tekstowej który pokazuje antyspamowy " kod " i, krytycznie, monit dla pola formularza, z którym jest używany. Po drugie, potrzebny będzie skrypt e-mail, który będzie akceptował aliasy (np. FormMail i wiele innych). Utwórz w formularzu wymagane pole z nazwą "odbiorca" (lub dowolną nazwą pola, na które twój skrypt e-mail oczekuje wysłania danych wejściowych formularza). Wyświetla grafikę " kod " z wbudowanym monitem obok. Upewnij się, że skonfigurowałeś skrypt poczty e-mail tak, aby akceptował użyty kod w grafice jako alias dla prawdziwego odbiorcy e-mail (ty). Kiedy to zostanie zaimplementowane, człowiek może łatwo odczytać i wprowadzić kod wybrany w grafice(tj. alias e-mail skonfigurowany w skrypcie e-mail). Robot spamowy widzi tylko puste pole. Jeśli robot wybierze losowo wypełnienie tego pola, wygeneruje błąd w skrypcie e-mail mówiący, że odbiorca nie istnieje. Nigdy nie widzisz tego błędu, ani nigdy nie dostajesz spamu. Próbowałem większości innych podejścia opisane w innych postach tutaj, ale żaden nie był w 100% skuteczny jak ten był. Oczywiście człowiek może to pokonać, ale jeśli to zrobi, po prostu zmień grafikę i alias e-mail w konfiguracji skryptu. Następnie musi zacząć od ręcznego poddania się.

 -1
Author: docz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-10-27 19:03:14