2024年10月のある日、メールボックスを開いたら受信数が3000件を超えていました。しかも毎分増えていく。
送信元をたどると、自分のブログの問い合わせフォームでした。
先に言っておくと、特別なことは何もしていません。入門記事のとおりに作った、ごく普通の構成です。だからこそ、同じ状態の方は少なくないと思います。
この記事では、原因になった設定と確認ポイント、そして2年後に基盤を入れ替えたらどうなったかを書きます。
3274件のメール
日本語になっていない英字列のメールが、次から次へと届いていました。あとで数えたら、その日の 0:23 から 19:15 までで 3274件。
内容は謎の URL を含むもので、別々のメールアドレス宛に同じ文面が送られていました。つまり自分のブログが、無差別なスパム送信の中継地点として使われていたわけです。
まず止める
原因究明より先に、ブログの公開を停止しました。
すると毎分届いていたメールの雨が、ぴたりとやみました。ここで「自分のサイトが原因」がほぼ確定します。
順番としては、これでよかったと思っています。動いている限り被害は増え続けるので、止めてから調べる。
原因を切り分ける
ブログをプライベートモードで表示し、メールが出る経路を順に潰していきました。
心当たりは2つです。コメント欄と問い合わせフォーム。
- コメントを投稿 → メールは届くが、形式が違う
- 問い合わせを送信 → 届いていたスパムとそっくりな形
フォームで確定しました。
犯人は Contact Form 7 の「自動返信」だった
調べてみると、問い合わせフォームがスパムに使われるのはよくある話でした。同じような相談や記事がいくつも見つかります。
当時のフォームは Contact Form 7 というプラグインで作っていました。そして、よかれと思って問い合わせ内容の控えメール(自動返信)を有効にしていました。
ここが穴でした。
自動返信メールの宛先は、フォームに入力されたメールアドレスです。
つまりフォームは、入力された任意のアドレスへメールを送れる装置になっています。攻撃側から見れば、送りつけたい相手のアドレスを入力欄に書けばいい。そのうえ私は、控えメールに問い合わせ内容をそのまま差し込む設定にしていました。本文まで相手の自由になります。
あとはこちらのサーバーが、正規の送信元として代わりに送ってくれる。
これが「踏み台」の中身です。私のサーバーは、私の知らないところで、他人にメールを配り続けていました。
もう一つ、reCAPTCHA が効いていませんでした。ブログには設定済みだったので油断していたのですが、Contact Form 7 は入れただけでは reCAPTCHA と連携されません。プラグイン側の設定と、フォーム側の指定と、2か所そろって初めて機能します。
対処は次の2つです。
- 自動返信を止めた
- Contact Form 7 と reCAPTCHA を正しく連携した
効くのは 1 です。2 は自動化された投稿を減らすだけで、送信口そのものが空いていれば意味がありません。
公開を再開したところ、大量のメールは起こらなくなりました。
同じ構成の方へ:確認したい5つ
プラグインが何であれ、考え方は同じです。
1. 自動返信を使っているか 使っていないなら、切るのがいちばん確実です。無くて困る場面は、個人ブログならほとんどありません。
2. 使うなら、本文にユーザー入力をそのまま載せない 定型文だけにします。入力内容をそのまま差し込むと、本文が攻撃者の自由になります。
3. フォームから、自分以外の宛先にメールが出る設定になっていないか ここが本質です。自分宛に届くだけのフォームは踏み台になりません。 第三者に送れる経路があるかどうかを見てください。
4. reCAPTCHA が実際に連携されているか 「設置した」と「効いている」は別です。私はここを取り違えていました。
5. 異常に気づける経路があるか 私が気づけたのは、フォームの通知が自分の受信箱に届く設定だったからです。送信のたびに自分にも届くので、結果的に受信箱が異常の知らせ役になっていました。監視のつもりで用意したものではありません。ただ、通知の宛先を普段見る場所にしておくだけで、気づくまでの時間は変わります。
3274件の宛先について
3274件を少し確認すると、別々のアドレス宛に同じ内容が送られていました。
つまりこの19時間、私のサイトは見知らぬ誰かに迷惑メールを送り続けていたことになります。困っていたのは自分だけではありませんでした。原因究明より先に止める、と最初に書いたのはそのためです。
宛先のアドレスはどこかから漏れたものでしょうし、自分のアドレスも同じように流出しているのだろう、とも思いました。セキュリティ被害は、いつ誰に起きるか分かりません。
ここまでが2024年の話です。話は、ここで終わりませんでした。
2年後、別の理由で基盤を変えた
2026年、このブログを WordPress から静的サイトへ移しました。静的サイトというのは、あらかじめ作っておいた HTML ファイルを、そのまま配るだけの仕組みです。
| 旧 | 新 | |
|---|---|---|
| サイト | WordPress(レンタルサーバー) | Astro(静的サイトジェネレーター) |
| 配信 | 同上 | Cloudflare Pages |
| 記事の管理 | 管理画面 | GitHub のリポジトリ |
| 問い合わせ | Contact Form 7 | Google フォーム(埋め込み) |
動機はセキュリティではありません。 維持コストと管理の手間を減らしたかった、それだけです。2年前の件は、このとき念頭にありませんでした。
気づいたら、対策が要らなくなっていた
移行から少し経って気づきました。あの問題は、もう起こりようがありません。
理由は単純で、踏み台にされる部品がそもそも無いからです。
- 問い合わせフォームを自前で持っていない(Google フォームに任せている)
- コメント欄が無い
- 管理画面が無い(記事は GitHub にファイルを置くだけ)
- プラグインが無い
- サーバー側で動くプログラムもデータベースも無い
リクエストを受けて何かを実行する場所が無いので、そこを突かれることもありません。
reCAPTCHA を設定して穴を塞ぐのとは、方向が違います。穴のある部品ごと持たなくなったという話です。
ただし、これは「サーバー側で動くものを狙う攻撃」が当てはまらなくなっただけです。GitHub と Cloudflare のアカウント、ドメイン、外部から埋め込んでいる部品は残っています。フォームも Google に任せているだけです。消えたのではなく預け替えた、守る対象が移った、というのが正確なところです。
WordPress は過剰だったのか
正直に書いておきます。当時、過剰だとは思っていませんでした。
ブログを始めたのは技術的な興味もあってのことで、「その世界の常識を知りたい」というお試しの面がありました。WordPress は情報が多く、学ぶ対象としては良い選択でした。あの時点の判断として間違っていたとは思いません。
ただ、運用という一点で見れば過剰でした。私がやりたかったのは記事を書いて公開することで、それ以外の機能はほとんど使っていません。使っていない機能にも、更新と設定とリスクは付いてきます。
とはいえ、静的サイトに移ったことを「学びを終えて運用に落ち着いた」とは思っていません。
Astro も Cloudflare も GitHub も、私にとっては新しい対象でした。管理画面で書いて公開ボタンを押す代わりに、ファイルを書いて Git に反映する。プラグインを入れる代わりに、自分で仕組みを足す。やり方がまるごと変わるので、そのぶん学び直しがありました。
つまり、学ぶのをやめて楽な方へ移ったのではなく、学ぶ対象が入れ替わったというのが実際のところです。
WordPress で覚えたことは無駄になっていません。何がどう動いていて、どこにリスクがあるのかを一度触って知ったからこそ、いまの構成で「何を持たずに済んでいるか」が分かります。
おわりに
いま同じ症状が出ている方へ、動く順番をまとめます。(設定の点検は、前半の「確認したい5つ」を見てください。)
- まずサイトを止める(原因究明より先)
- コメント欄・フォームに順にテスト投稿して経路を特定する
- 自動返信を止める(第三者宛の送信口になるため)
- reCAPTCHA が実際に連携されているか確認する
そのうえで、もう一つの選択肢を置いておきます。
「対策を足す」以外に、「そもそも持たない」という手があります。
自分の用途に対して機能が余っているなら、構成を選び直したほうが早いことがあります。
ただし私の場合、これは狙って選んだ対策ではありません。別の理由で移った結果、たまたまそうなっただけです。だから「静的サイトにすれば安全」とは書きません。書けることはひとつで、いま自分が何を持っていて、そのうち何を使っていないのかは、一度数えてみる価値があるということです。