SEの進地です。こんにちは。
このアークウェブビジネスブログでは現在以下の二つのコメントスパム対策を施しています。
1.MT-Akismetプラグインの利用
2.Forcing Comment Previewsを3.3用に作成
今回はこのスパム対策(特に後者について)説明します。
前者のMT-AkismetはAkismetによるPukiWikiへのspam(スパム)防止機能で紹介されているAkismet API(http://akismet.com/)をMTから利用できるようにするプラグインです。インストールするだけで自動的にコメントのスパム判定を行って、スパム判定したものは迷惑コメントに振り分けてくれます。
しかしMT-Akismetは、MTのDBへの登録は受け付けてしまいます。今朝方調べてみると、弊社のこのビジネスブログには累計で2万件以上のコメントスパムがポストされていて、かつ、日に10件以上はDBへの登録を受け付けていることがわかりました。これは負荷の観点からも見逃せません。
そこで、コメントスパムのDBへの登録自体を行わないようにするため、後者の対策を行いました。
後者のコメントスパム対策は元はMusingsの"Forcing Comment Previews"という記事で紹介された方法で、ロボットがプレビュー画面を経由せずに直接コメント受付プログラム(mt-comment.cgi)にアクセスしてくることを利用して、プレビュー画面経由でなければコメントを受け付けないようにする方法です。
具体的には
・コメント投稿フォームから「投稿」ボタンを消す
・プレビュー画面から投稿を行ったことの判定として、プレビュー画面にhashを仕込む
・コメント受付プログラム(mt-comment.cgi)の方ではhashが正しい値でなければ投稿を受け付けないようにする
というカスタマイズを施します。
この対策方法は「Going My Way:プレビューボタンのみ表示してhashを仕込むというコメントスパム対策」など、わりと知られた対策のようなのですが、MT3.3に対応させる情報がなかったので、自分で実装してみました。
編集するのはたった二つのファイル(lib/MT/Template/ContextHandlers.pm、lib/MT/App/Comments.pm)です。差分は下記でダウンロードできます。
・lib/MT/Template/ContextHandlers.pmの差分
・lib/MT/App/Comments.pmの差分
この2つの差分を適用したら、pluginsディレクトリにsalt.txtという名前のファイルを作成して、中に半角英数で任意の文字列を書いておきます。
最後に、アーカイブテンプレート内のコメントフォームの箇所から投稿ボタンを削除、またはコメントアウトして完了です。各エントリーのコメントフォームに「投稿」ボタンが表示されず、プレビューから「投稿」ボタンを押すとコメントが投稿されることを確認します(※1)。
lib/MT/Template/ContextHandlers.pm、lib/MT/App/Comments.pmで行ったカスタマイズを簡単に説明しておきます。
lib/MT/Template/ContextHandlers.pmでは、コメントプレビュー時にhiddenタグの名前validatedにハッシュを仕込むロジックを追加しています。ハッシュはコメント文、エントリーID、投稿者のIP、投稿者名、投稿者メールアドレス、投稿者URLをつなげたものを、salt.txtに記述した種を使ってSHA1形式でハッシュ化したものです(※2)。
lib/MT/App/Comments.pmも同様で、こちらはコメント受付処理直前にフォームから送られてきたデータからlib/MT/Template/ContextHandlers.pmと同様のルールでハッシュを作成し、送られてきたハッシュと等しければDBに受け付ける、等しくなければエラーを出して終了というロジックを追加しています。
Forcing Comment Previewsに記述されているように、コメントプレビュー用テンプレートを修正していないのは、3.3ではコメントプレビューのformタグは<MTCommentFields preview="1" static="1">という一つのMTタグで表現され、完結してしまっているために、テンプレートの修正ではこのform内にhiddenタグを追加する方法を思いつかなかったからです(※3)。そのため、MTCommentFieldsを解析してタグを出力しているlib/MT/Template/ContextHandlers.pmの_hdlr_comment_fieldsメソッドを直接カスタマイズしています。
※1
仮にコメントフォームの箇所に投稿ボタンが表示されたままでも、この段階ではフォームにハッシュが仕込まれていないので投稿は受け付けられません。
※2
従って、この対策を施すにはシステムにPerlのDigest::SHA1がインストールされている必要があります。
※3
もっとよい方法をご存じの方、是非コメントくださいm(__)m JavaScriptオンを強制でよければ、onloadでhiddenに追加とか思いついたんですが。