最近、スパムコメントやトラックバックが多くてウザいと言っている方がたくさんいます。
そこで、スパム対策スクリプトを書いてみました。このブログでは、意図どおりに動いています。
当ブログにスクリプトを設置したのは2013年6月15日午前0時ですが、今のところスパムはゼロです。ただ、このブログには元々スパムが少ないので、スクリプトの成果が出ているのかどうかは判断できません。
追記:
スパム送信側が、このページで公開したソースを読めばブロックは破られてしまいます。なので、ソースは非公開でこっそり使うのが正しいですが、あえて公開します。
詳しいことは後述しますが、本来、スパムの対策をJavaScriptで書くのは無意味です。ですが、あるスパムはHTMLを取得して解析し、コメントやトラックバックの送信先アドレスを抽出しているのが間違いありません。それで、この対策スクリプトが有効に作用するかどうかを探りたいと思います。
このスクリプトを使用中の、その他のブログ
- イタリアンな日々
- 設置日:2013年06月15日
- goods and life +
- 設置日:2013年06月18日
- 楽して稼ぎたい〜お小遣い稼ぎ情報局〜
- 設置日:2013年06月18日
*注2:2013年6月17日 「トラックバックでスパムフィルターが有効であることを知らせる」を無効にしないと、URLが読まれます。
このスクリプトはファンブログ専用です。ただ、ロジックを理解していただければ、ファンブログ以外でも改変して使えます。改変はご自由にどうぞ。
ちなみに、これを導入すると、JavaScriptが無効なブラウザからはコメントが送れなくなります。しかし、画像認証を使っていてもそれは同じです。
送信先URLを抽出できなくする
今回書いたスクリプトがやっているのは、URLの隠蔽です。URLを隠すことで抽出できなくします。
ファンブログのスキンに、次の2ヵ所があります。
{$BlogCommentPostUrl$}
{$BlogEntryTrackbackLink$}と書かれた場所には、トラックバックURLが書き込まれます。
同様に{$BlogCommentPostUrl$}には、コメント送信先URLが書き込まれます。
今回のスクリプトは、それを以下の手順で処理します。
- 2つのURLを該当個所に書き込まず、別の場所に書いておいて、そのHTMLをサーバーが送信する。
- HTMLをブラウザで読み込んだ後、別の場所に書かれているURLを正規の場所に書き直す。
スパム側はスパム側で、別のスクリプトを使ってURLを抽出しようとするでしょう。しかし、あるはずの場所にURLがなければ読み込めないと思います。
スクリプト導入の前処理
変更が必要なスキンは「1記事」だけです。「1記事」のスキンの2ヵ所を変更します。
まず{$BlogEntryTrackbackLink$}を削除します。結果は下の様になります。
<div id="trackbackText"> この記事へのトラックバックURL<br /> <SpamFilterTrackbackNotice><a>{$BlogEntryTrackbackLink$}</a> </SpamFilterTrackbackNotice><br /> </div>
<div id="trackbackText">
この記事へのトラックバックURL<br />
<SpamFilterTrackbackNotice><a></a>
</SpamFilterTrackbackNotice><br />
</div>
次に{$BlogCommentPostUrl$}をjavascript:void(0);に変更します。
<div id="commentForm"> <BlogEntryIfAllowComments> <BlogEntryIfAllowPostComments> <h3 id="commentTitle">コメント</h3> <div class="text">{$CommentErrMsg$} <form method="post" name="WriteCommentForm" action="{$BlogCommentPostUrl$}"> <table border="0" cellspacing="0" cellpadding="0"> (以下略)
<div id="commentForm"> <BlogEntryIfAllowComments> <BlogEntryIfAllowPostComments> <h3 id="commentTitle">コメント</h3> <div class="text">{$CommentErrMsg$} <form method="post" name="WriteCommentForm" action="javascript:void(0);"> <table border="0" cellspacing="0" cellpadding="0"> (以下略)
これであるハズの場所に、URLはなくなりました。
スクリプトの導入
URLを本来の場所に書き戻すために、今回作ったスクリプトはこれです。スパム送信側は、これがわからないのでURLは見つからないはずです。
<!-- スパム撃退スクリプト ここから --> <script type="text/javascript"><!-- (function(){ var tb=document.querySelector('div#trackbackText a'); var form=document.querySelector('div#commentForm form'); if(tb){ tb.innerHTML='{$BlogEntryTrackbackLink$}'; } if(form){ form.action='{$BlogCommentPostUrl$}'; } })();//--> </script> <!-- スパム撃退スクリプト ここまで -->
このスクリプトを、そのままコピーして「1記事」スキンの最後の方にある{$BlogAccessCounter$}の上に追加します。スクリプト1行目の<!-- スパム撃退スクリプト ここから -->と、最後の<!-- スパム撃退スクリプト ここまで -->は、なくてもいいのですが、後で削除や書きかえを行なう際に目印になるので、このまま書き込んでください。
<div id="footer"> </div><!-- /footer --> </div><!-- /container --> ここにスクリプトを追加 {$BlogAccessCounter$} </body> </html>
スクリプトの赤字部分trackbackTextとcommentFormは、スキンのidと照合して、同じ名前かどうかを確かめてください。もし名前が違うなら、スキンのidと同じ名前に書きかえて使ってください。
設置後は自分でコメントとトラックバックをテスト送信して、ちゃんと送れることを確認してください。自分で試さないと、書き込めなくなっていても誰も伝えられません。(書き込めないので)
このスクリプトに効果があるなら、画像認証は不要になります。(ただし「コメント・トラックバックURLにランダムな認証キーを使う」の設定は必ず有効にしてください)
逆に、これでもスパムが来るのなら、それはHTML全文を正規表現でスキャンしているのだろうから、ダミーURLを噛ませれば対処できます。でもそれは、今はやりません。やると相手の手の内が読めなくなるので、技を小出しにして探ります。
今回のソース公開は、このスクリプトがスパム対策として有効かどうかを確かめたかったからです。ただ、このブログには元々スパムが多くありません。なので、導入した方は、スパムが来なくなったかどうかをコメントくださると助かります。
スクリプト作成に至った経緯
先日、スパム対策「コメント・トラックバックURLにランダムな認証キーを使う」は常にオンという記事を書きました。
その記事に書いたとおり「コメント・トラックバックURLにランダムな認証キーを使う」という設定を有効にすれば、コメントの画像認証と同じ役割を果たします。
しかし「URLにランダムな認証キーを使う」を有効にして、「画像認証」を止めたところ、大量にスパムが来たとのご報告をいただきました。
これは、どういうことかというと、そのスパムはHTMLを取得して解析し、コメントやトラックバックの送信先アドレスを抽出しているということです。
アドレスがわかれば、サイトを開く必要はない
スパム対策「コメント・トラックバックURLにランダムな認証キーを使う」は常にオンに書いたとおりで、ブログのURLというのは規則的なパターンで出来ています。そのパターンがわかっていれば、いちいちブログを開かずに、直接スパムコメントやトラックバックを送れます。
スパムコメントが書き込まれたからといって、ブログの記事は読まれていない、というか開かれていないのです。通常は。
ですから本来、スパムの対策をJavaScriptで書くのは無意味です。なぜなら、スクリプトのあるページは開かれることがなくスパムは送信されるので、スクリプトは作用しないからです。
しかし、ランダムURLのコメントフォームやトラックバックにスパムが届いたのであれば、それはページを開いてHTMLを取得した後、それを解析してコメントないしはトラックバックの送信先URLを抽出していることになります。
つまり、ランダムURLを調べるために、ブログを一回読み込んでいる。だったら、それ用のスクリプトを書いて、読めなくしてやろう。それなら有効に働くかもしれない。ということで書いてみたのが、今回のスクリプトです。
[追記]
画像認証はなぜ効果があるのか?
ランダムなURLが抽出されたのに、「画像認証」が破られないのはなぜでしょうか?答えは簡単で、それが、文字ではなく「画像」だからです。コンピュータにとって「文字」と「画像」は明確に違うものです。
人間が上の画像を見れば、そこに書いてあるのは「aSEeW@」という6文字だと認識できます。しかし、コンピュータにはわかりません。コンピュータにとって、それは文字ではなく「画像」だからです。人間にとっては文字でも、コンピュータにとっては「aSEeW@」という「形」が書いてある画像です。
「画像認証」が破られないのは、コンピュータが「aSEeW@」という文字を抽出できないからです。
ただ、個人的には画像認証はキライです。「画像認証が有効なブログは、スパムに屈したブログであって、本来ブログの管理者が費やすべきスパム対策の労力を、コメント投稿してくれる読者に押し付けている」と、そう思うからです。