2004年09月25日
コメントスパム対策
Bayesian filter for MTでスパムを一括削除できるようにしてあるが、削除する作業すら面倒。そもそもスパムと分かっているコメントは保存されないようにしたい。同じようなことを考えている人は絶対いると思うのだが、ちょっと探しても見つからなかったので、以下のようなことを試してみた。
lib/MT/App/Comments.pmの190行目と191行目
$comment->save;
$app->rebuild_indexes( Blog => $blog )
を以下のように書き換え。
$comment->save;
require MT::Bayesian;
my $by = MT::Bayesian->new;
$by->new_bayesian( {blog_id => $entry->blog_id, comment_id => $comment->id} );
if ($by->spam>0) {
$comment->remove;
$by->remove;
return $app->error($app->translate(
"Spam.", $app->errstr));
exit;
}
$app->rebuild_indexes( Blog => $blog )
これでベイジアンフィルタがスパムと判定したコメントは書き込めなくなった。本当は $comment->save の前に弾きたいのだが、うまく行かなかったので一旦保存して判定してから削除している。これでもリビルドは掛からないし、とりあえず満足。
2004-10-11 追記
しばらく使ってみると、フィルタの学力(笑)が足りないのか、しばしばスパムではないものも弾いてしまうことがあった。そこで以下のように変更した。
if ($by->spam>0) {
$comment->remove;
$by->remove;
return $app->error($app->translate(
"Spam.", $app->errstr));
exit;
}
を
if ($by->prob*100>50) {
#$comment->remove;
#$by->remove;
return $app->error($app->translate(
"Spam.", $app->errstr));
exit;
}
に変更。上の方では「スパムか否か」で判定していたところが、下ではもう少し細かく数値で指定できるようになる。$by->prob*100>50の「50」がmt-bayesian.cgiのManage Comments画面に表示されるSpam Probability。例えばうちに来るspamはほとんど全てが90%以上のProbabilityだが、spamではないものも時々70%とかになることがあるので、この数値を75程度にすることで誤判定が減ることを期待できる。
さらにコメントとその判定結果の削除を省略し、誤判定したコメントも後からManage Comments画面でspamではないと学習し直させ、復活可能にすることにした。結局こまめにメンテナンスが必要な状態に一歩後退してしまったが、立て続けに数十のスパム爆弾でリビルドが掛かりまくることを考えると、これでもまだマシ。
ベイズフィルタがもう少し賢くなったら再度問答無用モードに戻そうと思っている。
2004-10-14 追記
現在のところ以下のようにしている。
require MT::Bayesian;
my $by = MT::Bayesian->new;
$by->new_bayesian( {blog_id => $entry->blog_id, comment_id => $comment->id} );
if ($by->prob*100>70) {
#$comment->remove;
#$by->remove;
$app->log("Spam: $user_ip");
return $app->handle_error('スパムコメントの可能性があります');
}
$app->errorだと終了しっぱなしなので、$app->handle_errorにして、誤判定された人が修正しやすいようにしたのと、なぜかうまく働かない$app->translateを外した。
Refererなしスパムが大半の場合は、こちらの方法がベイジアンフィルタもいらないので簡単で手っ取り早い。
コメント
いただきました。ありがとう。
うちはv.2.65なので行の位置が違うけど,同等のところの置換で,そのまま動いてます。
コメントする