スプレッドシートに「jdnskndskjn」という名前の問い合わせが届いた。
電話番号は「+1-800-XXXXXXX」。メッセージはSEO案内の英文。明らかにボットだ。その施工会社の資料請求フォームに、スパムが流れ込むようになった。
スパムの前提を使う
その施工会社は日本国内のパートナービジネスを展開している。正規の申込者は全員、日本語の氏名と日本の電話番号を持っている。
「正規の申込者に必ず当てはまる条件」の逆を取れば、スパムを弾ける。この前提がバリデーションの設計になった。
第一段階:ハニーポット
人間には見えないフォームフィールドを設置する。
<input type="text" name="website" style="display:none" tabindex="-1" autocomplete="off">
通常のユーザーはこのフィールドを見ることができないため、空のまま送信される。スパムボットはフォームの全フィールドを自動入力するため、このフィールドにも何かを入力して送信する。
GAS側でwebsiteフィールドに値が入っていた場合、成功レスポンスを返しながら実際の処理はスキップする。スパムボットには「送信成功した」と思わせることで、再試行を減らす。
第二段階:名前の日本語チェック
if (!/[ぁ-ん]|[ァ-ン]|[一-龯]/.test(params.name)) {
return ok();
}
ひらがな・カタカナ・漢字のいずれかが含まれていなければスパムと判定する。その施工会社に資料請求する人が日本語以外の名前を入力することは、ほぼ想定しない。
正規表現の範囲として[ぁ-ん](ひらがな)・[ァ-ン](カタカナ)・[一-龯](CJK統合漢字)を使った。誤検知なく日本語の文字を識別できる。
第三段階:電話番号バリデーション
日本の固定電話・携帯電話は0始まりの10〜11桁だ。
const phone = (params.phone || '').replace(/[-\s]/g, '');
if (!/^0\d{9,10}$/.test(phone)) {
return ok();
}
ハイフンとスペースは先に除去する。入力者によって「090-1234-5678」「090 1234 5678」「09012345678」と書き方が違うが、除去後に判定する。「+81-90-XXXX-XXXX」のような国際電話番号形式は弾く。海外からのパートナー加盟は想定していない。
バリデーションの順序
3段階の順序は意図的だ。
ハニーポットを最初に確認することで、「名前・電話番号の判定ロジックが見えない」状態になる。ハニーポットを突破できたとしても、次に日本語チェックがある。日本語チェックを突破できても、電話番号バリデーションがある。
各段階を単独で使うより、組み合わせた方が突破が難しくなる。完璧なスパム対策は存在しないが、「このサイトを攻撃し続けるよりも別のターゲットを探す」という判断をボットに促すことが目的だ。
実装後、スパムは届かなくなった。
*次回は「車種別施工マニュアルシステムの設計——加盟店と本部が共有するナレッジ基盤」*
*シンプルシステム株式会社 代表 伊藤勝彦*