プロが教えるわが家の防犯対策術!

PHPメールフォームにスパム書き込みが多くなった為、対策したいのですが。

(1)テキストボックスにURLが書かれた時に、「URLの書き込みは出来ません」などのエラーの文言を返して、送信出来ないようにするためにはどのようなプログラムにすれば良いのでしょうか?

(2)半角英語スパムが多いので、上と共にひらがななど2バイト文字を含んで無いと、エラーの文言を返して送信出来ないようにもしたのです。

今日一日すぐ返信出来るようにしていますので、『指示して頂ければすぐ追記もします。』

ぜひともご回答よろしくお願いします。

A 回答 (5件)

 mb_send_mail で送る前に、通常、メールアドレスが正しいかどうか、またはメールアドレスやコメントが空欄などがないかチェックします。


 そこのところで、メールアドレスが入っている変数名を$email、文面の変数名を$comment とした場合(ku1395さんがお使いになっているPHPの変数名は分かりません)、エラー表示のfunctionをPHPファイル最下部にでも作成しておきます。既存でありましたらそのfunctionに送ってください。

 上記のチェックする最後のところにでも、

if( preg_match('/http/', $email) > '0' ) error( "URLの可能性があります");
if( preg_match('[/ぁ-ん]/', $comment) <= '0' ) error( "日本語ではないかも");

function error($msg){

echo "<html><body>\n";
echo "<center>\n";
echo $msg;
echo "</center>\n";
echo "</body></html>\n";
exit;

}

とかだと良いと思います。
shift_jisのPHPは作ったことないので良くわかりません。
もしかしたら、yyr446さんが記されています mb_regex_encoding("UTF-8"); を出力した後に、if( preg_match('[/ぁ-ん]/', $comment) <= '0' ) error( "日本語ではないかも"); かもしれません。

 こういうのは、小さなPHPファイルを作成して、そのパーツごとを記してチェックしてみると良いですよ。
 例えば、Shift_jisでの、以下のようなtext.php を作成し、$email の ' ' の間にいろいろなのを記して、テストしてみるとかがあります。

<html>
<body>
<?php

$email = '';

if( preg_match('/http/', $email) > '0' ) echo "URLの可能性がある";
else echo "URLではない";


?>
</body>
</html>

この回答への補足

yyr446さんのものを入力しますと。
「テキストにURLが含まれています。」と表示されている状態で、条件を変えても動作しませんでした。
理由は、私が基本的なPHPのルールを分かって無い為だと思います・・;;

$txtdataと$matchesは、例えば、$txtdata = $_POST['mail'] というような形で代入すれば良いのでしょうか?

入れているのはフォームは下記です。


<?php header("Content-Type:text/html;charset=Shift_JIS"); ?>
<?php

$script ="sendmail.php";
$to = "xxx@xxx.com";
$sbj = "アンケート";
$chmail = 1;
$jpage = 0;
$next = "http://www.xxxx.com/";
$from_add = 1;
$remail = 1;
$resbj = "送信ありがとうございました";
$esse = 1;
$eles = array('名前','年齢','性別','email','規約');


$sendm = 0;
foreach($_POST as $key=>$var) {
if($var == "eweb_submit") $sendm = 1;
}

// 文字の置き換え
$string_from = "\";
$string_to = "ー";

// 未入力項目のチェック
if($esse == 1) {
$flag = 0;
$length = count($eles) - 1;
foreach($_POST as $key=>$var) {
$key = strtr($key, $string_from, $string_to);
if($var == "eweb_submit") ;
else {
for($i=0; $i<=$length; $i++) {
if($key == $eles[$i] && empty($var)) {
$errm .= "<FONT color=#ff0000>「".$key."」は必須入力項目です。</FONT><BR>\n";
$flag = 1;
}
}
}
}
foreach($_POST as $key=>$var) {
$key = strtr($key, $string_from, $string_to);
for($i=0; $i<=$length; $i++) {
if($key == $eles[$i]) {
$eles[$i] = "eweb_ok";
}
}
}
for($i=0; $i<=$length; $i++) {
if($eles[$i] != "eweb_ok") {
$errm .= "<FONT color=#ff0000>「".$eles[$i]."」が未選択です。</FONT><BR>\n";
$eles[$i] = "eweb_ok";
$flag = 1;
}
}
if($flag == 1){
htmlHeader();
?>

以下はメール送信内容など。

補足日時:2009/06/22 21:40
    • good
    • 0

No1のyyr446です。


他の方から正規表現パターンの解答が既に出ています。
私も考えていたのですが、1つの正規表現パターン文で、
(1)httpの文字列を含まない
かつ
(2)ひらがなを1文字以上含む
を表現できないかと悩みましたが、あきらめました。
とりあえずif文を2回使えば、
mb_internal_encoding("UTF-8");
mb_regex_encoding("UTF-8");
if (preg_match("/^(?!.*HTTP).+$/i",$txtdata,$matches) > 0){
if(mb_ereg_match(".*[あ-ん]+",$matches[0])){
print "OKです。";
}else{
print "テキストに不正な文字が含まれています。";
}
}else{
print "テキストにURLが含まれています。";
}
でできました。
否定の先読みをうまくつかえば、一つのパターンで出来るような気がするのですが、あまり正規表現に精通してないもので、申し訳ありません。
他の解答を待ちます(他人の質問に便乗してすみません)
    • good
    • 0

1) URLなら、http:とかhttps:とかがあるので、


if( preg_match('/http/', $email) > '0' ) echo "URLの可能性があります";
 でも、これだとhttpはないけど@のない、つまりメールじゃない記号も入力可能になってしまいます。
 厳密には@マークの前に使って良い記号を含めた正規表現が必要かと思いますが。

2) ひらがなのない日本語はありえないとして、
if( mb_ereg('[ぁ-ん]', $comment) <= '0' ) echo "日本語ではないかも";

この回答への補足

お返事ありがとうございます。
私のPHP理解レベルが低いのですが、具体的にプログラムとして動くようにフォームPHPの中に設置することが出来ませんでして・・
(ネット上の物を既存のフォーム動作PHPに記入などして)動作させることが出来ませんでした。

もし出来ましたら、動作する設置例をご指摘頂けますと、解決出来るかもしれません。

具体的にどういうフォームPHPで?というのが必要でしたら言って頂ければ追記します。一般的なフォームPHPで、sendmail使用、文字コードShift_JISの物です。

補足日時:2009/06/22 18:25
    • good
    • 0

URL>


preg_match("/(http:\/\/|ttp:\/\/)/i",$text)
または substr_count(strtolower($text), 'http') > 0

日本語>
preg_match("/^[\x01-\x7e]+$/",$text)

でどうでしょう。

配列に禁止語句を設定して、foreachで1つずつチェックに掛けるというのも有効だと思います

この回答への補足

お返事ありがとうございます。
上と重複レスになるためご返信のお礼レスだけ。

補足日時:2009/06/22 18:39
    • good
    • 0

SPAM判定基準の仕様があいまいなような、一方厳しすぎるような


なので漠然としていますが。
(1)URLの判定は、単に"http:"又は"HTTP:"の文字列があるかないか調べるだけでよいのですか?
(2)数字や記号も2バイト文字でなければ×にするのですか?

いずれにせよ正規表現で入力された内容をマッチさせて、マッチしたら
エラーメッセージを返すという事ですね

この回答への補足

>>(1)URLの判定は、単に"http:"又は"HTTP:"の文字列があるかないか調べるだけでよいのですか?

はい、そうです。あれば送信されずエラーメッセージを出したいです。

>>(2)数字や記号も2バイト文字でなければ×にするのですか?

こちらは、書き込みにひらがなが含まれてないと送信出来ないものにしたいです。

>>いずれにせよ正規表現で入力された内容をマッチさせて、マッチしたらエラーメッセージを返すという事ですね

そうですね、(1)(2)に添わなければエラーメッセージを出し送信されない形が理想です。
エラーメッセージ部分は自分の作ったHTMLを表示出来れば尚良いですが、これについては出来る出来ないが分からないので、出来ればと言うところです。

ちなみに私のPHP理解度的には拾った物を組み合わせてる程度の初心者です。
ご回答よろしくお願いします。

補足日時:2009/06/22 16:00
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!