7年ぶりのブログ更新です。このサイトは長く ASP.NET Core で動かしていましたが、このたび全ページを静的HTMLに作り直しました。その作業で一番考えさせられたのが「問い合わせフォーム」でした。サイト制作では当たり前のように付ける部品ですが、実はサイトの中で一番危ない場所です。今日はその話を書きます。
フォームはサイトで一番狙われる場所
WordPress サイトへの侵入経路は、本体よりもプラグインが大半を占めます。その中でも問い合わせフォームのプラグインは特別です。ほぼすべてのサイトに入っているからです。定番のフォームプラグインは数百万サイトで使われており、ひとつ脆弱性が見つかると、その数百万サイトが同時に攻撃対象になります。攻撃側から見れば、フォームは「外部の入力を受け取ってサーバーで処理する」機能そのものなので、探す価値が最も高い入口です。
スパム対策は「防御側だけがお金を払う」構造になりがち
フォームを置けばスパムが来ます。長年の定番だった CAPTCHA(画像認証)は、AI が実用レベルで突破できるようになりました。Google の reCAPTCHA は従量課金の Enterprise 版へ誘導が進んでいますが、これは判定(アセスメント)ごとの課金で、防御に成功した判定にも課金されます。つまり攻撃されるほど請求が増える。ボットは無料で殴り続けられるのに、防御側は殴られるたびに支払う——この構造自体がおかしいと思いませんか。
自動返信つきフォームは「踏み台」になる
意外に知られていない問題がもうひとつあります。メールアドレスを入力すると自動返信が飛ぶフォームは、他人のメールアドレスを大量に入力されると、迷惑メールの発信源になります(メールボム)。自分のドメインの送信評価が下がり、本来のメールまで届かなくなる。対策には送信頻度の制限や、制限に達しても攻撃側に悟らせない応答設計が必要ですが、そこまで作り込まれた問い合わせフォームはまれです。
放置されたフォームが一番危ない
そしてサイトは、作ったあとに放置されます。更新が止まった WordPress のフォームは、脆弱性が公表されても直されないまま公開され続けます。この「放置された WordPress に何が起きるか」は、当サイトの漫画の新シリーズ「WordPressの危険性編」で描いていますので、あわせてどうぞ。
それで、どうしたか
このサイトが選んだ答えは、公開サイトから動的な処理をなくすことでした。全ページを静的HTMLにすれば、フォームの脆弱性も、サーバーの侵入も、そもそも実行されるプログラムが無いので起きません。
問い合わせは、メールで受けることにしました。フォームと違って送信者の実アドレスで届くので、本人性の確認にもなります。スパムは受信側のフィルタで防ぎます——これは送信側(フォーム)の防御よりずっと枯れた、実績のある技術です。
静的サイトの配信は Cloudflare Pages の無料枠で足ります。デプロイ用には cf-publish という小さな CLI を作って PyPI に公開しました(pip install cf-publish)。ビルドしたフォルダを1コマンドで公開でき、失敗してもロールバックできます。このサイトも同じ方法で公開しています。
まとめ
問い合わせフォームは「無料の小機能」ではありません。継続的な防御・監視・スパム対策のランニングコストを伴う、サイトで一番危ない機能です。サイトを作る(作り直す)ときには、一度立ち止まって考えてみてください——そのフォーム、本当に必要ですか。メールではだめですか。