このHPも、書き込みは少ないながら、一応掲示板システムを持っている。ところが、世の常で、海外からと思われるイタズラ書込みがかなり頻繁で、有効な書込みが埋もれてしまう。
これらの書込みの多くが、海外のロボットによる自動書込みと思われる。対策として掲示板によっては、自動読み取りが困難なくらい崩したランダムな文字列を画像で表示してそれをユーザに書込んでもらい、照合してパスするものもある。
しかし、上記のように私の掲示板に書込まれるのは海外からのアクセスによっているので、こうしたゲストの手間を煩わせないで、単純に「日本語か?」ということでチェックしている。参考までに以下に、最新のスパム撃退用の Perlコードを示す。
1年以上、こうしたスパム書込みをチェックした結果、
1.漢字コードが使われていない。
2.特に平仮名は全く登場しない。
3.必ずと言っていいほど、URLを幾つか含めた宣伝をしている。
4.一定時間で巡回していると思われ、同じ IPアドレスからの書込みが多い。
ということで、上の1-4を順番にチェックをするのが以下のコード。
最後のコメントに入れたように、全部のチェックを終わった後で $err_cmt という文字列をチェックしてみて、それが空でなかったら何らかのスパムと判断して、正常な書込みルーチンを抜けてエラーにする。ただし、「全角文字がない」というようなチェック内容はあまり表示しない方が賢明。ほとんどはロボットなので、いちいちエラー表示を見てはいないと思うが、分かってしまえば、幾つかの対応コードをペーストしておけば回避できてしまうので、わざわざ知らせないほうがいい。
# ここから 文字列 TITLEに全角文字が含まれるかのチェックコード
001 $A = $in{'TITLE'};
002 jcode::convert(\$A, 'euc'); #EUCコードに変換
003 # $A を文字単位に分割して配列 @chars に代入する
004 $ascii = '[\x00-\x7F]';
005 $twoBytes = '[\x8E\xA1-\xFE][\xA1-\xFE]';
006 $threeBytes = '\x8F[\xA1-\xFE][\xA1-\xFE]';
007 @chars = $A=~ /$ascii|$twoBytes|$threeBytes/og;
# 配列 @chars に全角文字が含まれているか判定する
008 for ($i=0; $i < @chars; $i++ ){
009 $Aa = $chars[$i]; # 1字ずつ取り出して文字種を判別する
010 # 全角文字か?
011 if ($Aa =~ /[\xA1-\xFE][\xA1-\xFE]/) {
012 $jz++; # 全角文字数
013 }
014 }
015 if ($jz < 3) {$err_cmt = "★chrcode_error" ;}
# ここから 文字列 VALUEに全角平仮名が含まれるかのチェックコード
020 $A = $in{'VALUE'};
021 jcode::convert(\$A, 'euc');
# $A を文字単位に分割して配列 @chars に代入する
022 $ascii = '[\x00-\x7F]';
023 $twoBytes = '[\x8E\xA1-\xFE][\xA1-\xFE]';
024 $threeBytes = '\x8F[\xA1-\xFE][\xA1-\xFE]';
025 @chars = $A=~ /$ascii|$twoBytes|$threeBytes/og;
# 配列 @chars に平仮名が含まれているか判定する
026 $jz = 0;
027 for ($i=0; $i < @chars; $i++ ){
028 $Aa = $chars[$i]; # 1字ずつ取り出して文字種を判別する
# 平仮名か?
029 if ($Aa =~ /\xA4[\xA1-\xF3]/) {
030 $jz++;
031 }
032 }
033 if (jz < 10){ $err_cmt = "●hiragana_error" ;}
# ここから 文字列 VALUEに URLが2個以上含まれているかチェックする
040 $urlnm = ($in{'VALUE'} =~ s/http/http/ig);
041 if ($urlnm >= 3) {
042 $err_cmt = "★url_exist ;
043 }
# ここから スパム書込みリストのDN/IPアドレスと照合して、合致したら拒否する
# $host にアクセスしてきたHostのDN/IPアドレスが入っており、$rjct_file に
# 投稿を拒否したい DN/IPアドレス のリストを記述しておく
050 local(@SpmLst) = &ReadSpmLst($rjct_file);
051 for ($i=0; $i < @SpmLst; $i++){
052 @SpmLst[$i] =~ s/\s//g;
053 if ($host eq @SpmLst[$i]){
054 $err_cmt = "★reject_host";
055 last;
056 }
057 }
# $err_cmt をチェックして、空でなかったらエラールーチンをコールする
|
なお、こうした撃退方法がどれくらい効果が上がるのか分からないので、試しに撃退した書込みだけを別ログに記録してみて驚いた。何と 1週間に 6,000回近い書込みがあり、そのうちの 8割以上は、削除用のパスワードの未記入、1割以上が漢字コードの未使用、残りが 広告用URLと平仮名未使用、そしてそれらをすり抜けてしまったためブラックリストに登録した DN/IPアドレスからの書込みだと分かった。(幾つかのチェックに引っかかる書込みの場合は、チェックが早い方に引っかかるので、こうした割合になる)
実験はしてないが、上記結果から パスワードのような独自の必須入力項目と本文への平仮名使用をチェックするだけでもほとんど同じ効果が期待できそう。