Perlの小箱掲示板 いたずら スパム ブロック 方法 漢字コード 変換 EUC

その4:掲示板へのイタズラ書き込みブロック方法

 
この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アドレスからの書込みだと分かった。(幾つかのチェックに引っかかる書込みの場合は、チェックが早い方に引っかかるので、こうした割合になる)
実験はしてないが、上記結果から パスワードのような独自の必須入力項目と本文への平仮名使用をチェックするだけでもほとんど同じ効果が期待できそう。

top indexCookieの送受信Perl Index
NAME.gif
総アクセス数