日曜日, 5月 17, 2009

cgi全角文字チェック

英語スパムが掲示板に大量に来るので、まず英数チェックで対策。

はじめは以下のように、英数文字だけならOUTとしてみた。

#スパム対策

if( isAlNum($name) ){
  &error("<br>入力が制限されています。");
}
if( isAlNum($title) ){
  &error("<br>入力が制限されています。");
}
if( isAlNum($msg) ){
  &error("<br>入力が制限されています。");
}

sub isAlNum{
  my $str = shift || return(undef);

  #-- 英数字のみか --#
  if( $str =~ /^[a-zA-Z0-9]{1,}$/ ){
    return(1);
  }
  #-- 英数字以外が含まれる --#
  else{
    return(1);
  }
}

参考:CGI・Perl】半角英数字のみかチェックする


しかし、件名や名前に記号を入れられてチェックできず。
そこで、英数だけでなく記号も含むように以下のように改造。

sub isAlNum{
  my $str = shift || return(undef);

  #-- 英数字のみか --#
  if( $str =~ /^[!-~]{1,}$/ ){
    return(1);
  }
  #-- 英数字以外が含まれる --#
  else{
    return(1);
  }
}
しかし、これには半角スペースは含まれないので、
件名や名前に半角スペースが入るとOUT。

全角文字チェックがあったので、変更。

  my $str = shift || return(undef);

if ($str =~ /[\xA1-\xFE][\xA1-\xFE]/) {
  return(0);
}

else {
    return(1);
}
ところがこれは、eucのみで動作らしいので、動かず。

そこで、jcodeを使って無理やりeucに変換。
my $strは変換できないそうなので、cgi全部チェックして
$strを使ってないことを確認して、myをとる。

  $str = shift || return(undef);

jcode::convert(\$str, 'euc');

if ($str =~ /[\xA1-\xFE][\xA1-\xFE]/) {
  return(0);
}

else {
    return(1);
}


念のため、エラーもホスト情報でチェックしていると偽装

#スパム対策

if( isAlNum($name) ){
  &error("<br>$host は、アクセス制御されています。");
}
if( isAlNum($title) ){
  &error("<br>$host は、アクセス制御されています。");
}
if( isAlNum($msg) ){
  &error("<br>$host は、アクセス制御されています。");
}

なにもスパマーにエラー理由を正直に教える必要はないなと考え。

運用から12時間、現在のところは1件も入っていない。
まずは成功か・・・














Technoratiのタグ

0 件のコメント: