web-dev-qa-db-ja.com

PHP Web連絡フォームのスパムを防ぐ

私はアマチュアのWebデザイナーです。stackoverflow.comや他のWebサイトで検索し、この問題に対する多くの修正を見つけましたが、どれも機能していません(おそらくそれらを正しく実装していないためです)。より多くの知識を持っている人が簡単な修正を手伝ってくれるか、見つけた修正の1つを実装する方法を教えてくれることを望んでいます。

問題:ビジネスのウェブサイトに非常にシンプルなphp連絡フォームがあります。それは何年もうまく機能しましたが、先週ハッキングされました。現在、コメントなしで1日に数百件の問い合わせフォームが送信され、メールアドレス(明らかに有効な)と名前フィールドに文字列(「58ee8b52eef46」など)しかありません。

私はこのスパムを防ぐためにいくつかのテクニックを試しましたが、それらは私のphpフォームを破るか、スパムを防ぎません。 可能であれば、Captchaの歪んだテキストテストを必要とせず、フォームのすべてのフィールドに入力する必要のないソリューションが必要です。

完全な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();
?>
10
user7858610

簡単なトリックは、ハニーポットフィールドを作成することです。

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();
31
Steve

フォームフィールドを作成し、ユーザーに対して非表示にします。 phpスクリプトで、このフィールドが送信されたかどうかを確認しますが、空です。これで、リクエストがフォームとユーザーからのものであることがわかりました。

スパムは非表示フィールドを埋めます。または、PHPスクリプトを直接使用する場合、スパム保護フィールドは設定されません。

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;
}

Phpフォームスパムを保護する方法の詳細については、こちらをご覧ください。 https://zinoui.c​​om/blog/protect-web-forms-from-spam

2
BenRoe

非表示フィールド、愚かな質問(3 + 4とは?)などは、フォーム上のスパムのブロックにはあまり効果的ではありません。

私はこれを数年前に調査し、「FormSpammerTrap」と呼ぶソリューションを思いつきました。 JavaScriptコードを使用して、必須フィールドのフォーカス/オンクリックを「監視」します。自動化されたプロセスは、特定のサイト用に高度にカスタマイズされていない限り(スパムボットの所有者が望むよりも時間がかかる)、必須フィールドに「フォーカス/オンクリック」できません。

www.FormSpammerTrap.com サイトに無料のソリューションがあります。そして、スパムボットがスパムを試みることができるフォームがあります...そして彼らは、3年以上の間、そうしませんでした。あなたはそれを試してみてください...それはすべてオープンソースですので、それがどのように機能するかを見ることができます。 (そして、あなたがフォームを使用する場合、私はあなたのメールを収集しません。一度返信してから、あなたのメールを削除します。)

私の手法は、スパムボットをブロックするのにはるかに効果的です。彼らはそのサイトのコンタクトフォームをスパムボットすることができませんでした。

2
Rick Hellewell

私にとってはもっと簡単なアプローチです。文字通り、私が受信したすべてのスパム(d)には、メッセージにURLが含まれていました。そのため、私はそれでフィルタリングし、それ以来スパムメッセージを受信して​​いません。私は週に約10を取得していました。

あなたの行の下にこれを追加します$ error_message = ""; php-file:

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

Preg_matchの/ iは、大文字と小文字を区別しません。 「http」は「https」もフィルタリングします。

1
Joseph K

受け取っているスパムにコメントがない場合、単純にチェックを追加してみませんか?本物の人間の訪問者がコメントなしでコンタクトフォームを送信する理由はまったくありません。

キャプチャを追加したくないので、短期的に最も簡単な解決策は、コメントが最小文字数であり、少なくとも一定数の単語を含むことを確認することです。

例えば:

$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.');
}

これは、コメントに少なくとも20文字と少なくとも3つのスペース(4ワード)が含まれていることを確認する非常に簡単なチェックです。必要に応じて微調整します。

0
rickdenhaan