印刷用表示へ切り替え 通常表示へ切り替え 更新履歴を表示 更新履歴を隠す
MovableType プレビューを強制する迷惑コメント対策

海外からの迷惑コメント投稿が増えてしまったので,一旦プレビューしないとコメントを投稿できないようにした。

■ ■ ■

迷惑コメントが増えてきた。このサイトでは,2バイト日本語文字が含まれているコメントだけを受け付けるという対策を行ってきた(nlog(n): 日本語限定コメントスパム対策)。迷惑コメントのほとんどは1バイト文字の方々であり,有用なコメントの投稿例は1件もなし。そこで,1バイト文字の方々はあっち行っちゃえ的な「鎖国」政策をとってきたのである。しかし,最近になってこれを破るコメントが増えてきた。記事の本文をコピペすることで,2バイト文字を含めてきたのである。「開国してく〜ださ〜いよぉ〜喜怒哀楽?」というメッセージなしに,いきなり大砲をバカスカ撃ってきたのだ。こりゃたまらんわい,と言うことで対策に踏み切ることにした。

最近は CAPTCHA (Captcha - Wikipedia) を使って対策するのがトレンドになっている。Movable Type 3.2 以降であれば,プラグイン一発でできる素敵な方法がある(Captcha Plugin公開 - Ogawa::Memoranda)。しかし,バージョン 2.6 などには対応していない。何か別の方法でやるしかない。

環境は Movable Type 2.661 である。ここでは MTHash プラグインを使うことにした(Forcing Comment Previews | Musings)。導入に関しては Going My Way: プレビューボタンのみ表示してhashを仕込むというコメントスパム対策 が参考になる。繰り返すが,これは旧バージョンの MT 用である。新バージョンは CAPTCHA を使うのがよい。

インストール手順は次の通り。

  1. Perl モジュール Digest::SHA1 がインストールされていることを確認する
    $ find `perl -e 'print "@INC"'` -name '*.pm' -print | grep -i sha1
    /usr/lib/perl5/site_perl/5.8.2/i386-linux-thread-multi/Digest/SHA1.pm
  2. MTHash.pl をダウンロードして plugins ディレクトリに設置する
  3. plugins ディレクトリに salt.txt という名前のテキストファイルを置き,中に適当な文字列を半角英数字で書く
  4. 「Comment Preview Template」の form タグ内に次のコードを挿入する (改行はなし)
    <input
    type="hidden" name="validated"
    value="<MTSHA1SaltHash><MTCommentPreviewBody
    convert_breaks="0"><$MTEntryID$><MTCommentPreviewIP><$MTCommentPreviewAuthor$> <$MTCommentPreviewEmail$><$MTCommentPreviewURL$><$MTCommentPreviewSubject$><$MTCommentPreviewTextFilter$></MTSHA1SaltHash>"
    />
  5. lib/MT/App/Comments.pm に指定のコードを追加

最後の手順で,Forcing Comment Previews | Musings にある通りのコードを追加してテストしてみると,動作はするのだが若干問題があることが分かった。

コメント投稿フォームで,プレビューせずにいきなり投稿しようとして「Post」をクリックしたとき,次のメッセージが表示されるようになる。

Comment Submission Error
Your comment submission failed for the following reasons:
Please preview your modified entry before posting it.
Please correct the error in the form below, then press Post to post your comment.

これはよい。一度プレビューしてねという「Movable Type からのメッセージ」だからである。問題は,上の表示の下に次のような「Perl からのメッセージ」が表示されてしまうことである。

MT::App::Comments=HASH(0x826c77c) Use of uninitialized value in concatenation (.) or string at /home/絶対パス/lib/MT/App/Comments.pm line 172.
MT::App::Comments=HASH(0x826c77c) Use of uninitialized value in concatenation (.) or string at /home/絶対パス/lib/MT/App/Comments.pm line 172.
MT::App::Comments=HASH(0x826c938) Use of uninitialized value in string ne at /home/絶対パス/lib/MT/App/Comments.pm line 182.

このエラーは,コメント投稿フォームに subject, convert_breaks, validated の3つのパラメータが定義されていないために発生する。コメント投稿フォームからは「Post」ボタンを削除してしまうし,直接 CGI をたたいて迷惑コメントを送ってくるのはロボットだから,実害はなさそうに見える。しかし,システムのどこにインストールされているかが絶対パスで分かってしまうのは気分がよくない。そこで,Comments.pm に追加するコードに修正を加えることにした。

lib/MT/App/Comments.pm の「post」サブルーチン内に追加するコードを次のようにする。挿入する場所が分かるように,前後に元々の Comments.pm のコードを入れてある。

    if (!$q->param('text')) {
        return $app->handle_error($app->translate("Comment text is required."));
    }

# begin of hack for MTHash.pl
    require Digest::SHA1;
    my $sha1 = Digest::SHA1->new;

    my $author = defined($q->param('author')) ? $q->param('author') : "";
    my $email = defined($q->param('email')) ? $q->param('email') : "";
    my $url = defined($q->param('url')) ? $q->param('url') : "";
    my $subject = defined($q->param('subject')) ? $q->param('subject') : "";
    my $convert_breaks = defined($q->param('convert_breaks')) ? $q->param('convert_breaks') : "";
    $sha1->add($q->param('text') . $q->param('entry_id') . $app->remote_ip
               . $author . $email . $url . $subject . $convert_breaks);

    my $salt_file = MT::ConfigMgr->instance->PluginPath .'/salt.txt';
    my $FH;
    open($FH, $salt_file) or die "cannot open file <$salt_file> ($!)";
    $sha1->addfile($FH);
    close $FH;

    my $digest = $sha1->b64digest . "=";
    my $validated = defined $q->param('validated') ? $q->param('validated') : "";
    if ($validated ne $digest) {
    return $app->handle_error($app->translate(
            "Please preview your modified entry before posting it."));
    }
# end of hack for MTHash.pl

    my $comment = MT::Comment->new;
    $comment->ip($app->remote_ip);

強調部分が,Forcing Comment Previews | Musings のコードと異なる部分である。

$sha1->add() の引数に使っているパラメータ author, email, url, subject および convert_breaks の定義をチェックし,最後の方でも validated の定義がされているかどうかのチェックを追加している。パラメータが定義されていない場合,空の文字列を入れているが,適当な文字列を入れてもよいだろう。これで Perl のエラーメッセージが表示されてしまうという問題は解決する。コメント投稿フォームに author, email, url の入力欄がない場合でも Perl がエラーを出さなくなる。

プレビュー画面以外からは投稿できず,プレビュー画面から投稿できることを確認すればOK。プレビュー画面の HTML ソースを見るとハッシュ値がどのように設定されているか分かる。

<input type="hidden" name="validated" value="P/3ccH7ON0ScU5Az7Px/uyISMvc=" />

テストが終了したら,Individual Entry Archive テンプレートからコメント投稿用の「Post」ボタンを削除して終了である。必要があれば,Comment Listing Template などの(Comment Preview Template 以外の)テンプレートからも削除する。

迷惑コメントを指すのに「コメントスパム」という表現を使うことが多いが,迷惑メールを「メールスパム」って言わないよなと思い,最近は「迷惑コメント」と呼ぶことにしている。トラックバックについても同じように「迷惑トラックバック」で。「スパム」は誤解が生じやすいので使わない方向で(nlog(n): SPAM と spam は違うもの)。

コメント投稿に制限が多いのもよくないので,nlog(n): 日本語限定コメントスパム対策 はひとまず廃止で様子を見ることにした。

2014年4月14日追記:
この方法でも迷惑コメントが入るようになってしまったので,CAPTCHA を導入しました (nlog(n): Tiny Gimpy で迷惑コメント対策)。

Posted by n at 2006-11-10 01:44 | Edit | Comments (3) | Trackback(0)
Trackbacks

  • 「手違いで複数トラックバックを送ってしまった!」という場合でも気にしないでください (重複分はこちらで勝手に削除させていただきます)
  • タイムアウトエラーは,こちらのサーバの処理能力不足が原因です (詳細は トラックバック送信時のエラー をご覧ください)
  • トラックバックする記事には,この記事へのリンクを含めてください(詳細は 迷惑トラックバック対策 をご覧ください)
Comments

コメント投稿テスト。

Posted by: n at November 10, 2006 01:49

CAPTCHA は、色弱の人にとっては認識しづらい等の問題もあるようです。
最近、随分と採用するサイトが増えているようですが、採用する際にはよく検討する必要がありそうです。

Posted by: kirin_3 at November 13, 2006 17:45

そうですね。視覚障害の人のアクセスを妨げてしまうことについては,Wikipedia にも記述があります。
http://ja.wikipedia.org/wiki/Captcha
CAPTCHA は,機械可読性を下げるのが目的なので,人間の可読性も下がってしまうのは当然です。ということは,人でも認識できなくなってしまうこともあり得るということになりますから,このあたりはとても難しいところだと思います。

現時点では,画像を認識して突破してくるロボットは少なそうです。幸いにも,
http://as-is.net/blog/archives/001132.html
は文字や背景の変更が可能になっていますので,気になるのであれば,背景画像を真っ白にしてしまってもいいのではないかと思います。問題が少し先送りにされるだけですが。

Posted by: n at November 15, 2006 01:39
Post a comment
  • 電子メールアドレスは必須ですが,表示されません (気になる場合は「メールアドレスのような」文字列でもOKです)
  • URL を入力した場合はリンクが張られます
  • コメント欄内ではタグは使えません
  • コメント欄内に URL を記入した場合は自動的にリンクに変換されます
  • コメント欄内の改行はそのまま改行となります
  • 「Confirmation Code」に表示されている数字を入力してください (迷惑コメント対策です)


(必須, 表示されます)


(必須, 表示されません)


(任意, リンクされます)


Confirmation Code (必須)


Remember info (R)?