WAFを立てたのに、スパムはWAFの後ろを通っていなかった
小さなコーポレートサイトがあります。 公開して数日、問い合わせフォームにスパムが1件届きました。
実害はゼロ。中身は雑な宣伝です。 でも問題は2つありました。
ひとつ、スパム対策がまるでない。 もうひとつ、届いても誰も気づけない(通知経路がない)
で、私の手はもう動いてました。 「Cloudflareを前段に置いて、WAFとBot Fight Modeをオンにして、はい終わり」
反射です。 問い合わせフォームにスパム、と聞いた瞬間に出てくる、いつもの処方箋。 構成図を描き始めた自分の手のほうが、頭より先に動いていました。
フォームの中身を、まだ見ていなかった
処方箋を出す前に、一応フォームがどう動いているか覗きました。 これが効きました。
そのフォーム、サイトのサーバに何も送っていなかったんです。
ブラウザ上のJavaScriptが、公開されている匿名キーを使って、 BaaS(=ブラウザから直接データベースに書き込める外部サービス。よくある構成です)の APIに直接レコードを差し込む。それだけ。
つまり送信ボタンを押したときに飛ぶ通信は、
ブラウザ → その外部サービスのドメイン
であって、サイト本体のドメインを1ミリも経由していない。
……あれ。
Cloudflareは玄関に立っている。スパムは勝手口から入ってくる
ここでさっきの処方箋を見直します。
Cloudflareを前段に置くというのは、 サイト本体(ドメイン)に向かう通信を、Cloudflareが手前で受けて検問する、ということ。 WAFもBot Fight Modeも、サイトのドメインを通る通信を見て弾く仕組みです。
でもスパムの送信は、サイトのドメインを通らない。 ブラウザから、別のホスト(外部サービス)へ、直行便で飛んでいく。
玄関(サイト本体)にどれだけ立派な警備員を立てても、 スパムは玄関を使わない。勝手口から入ってくる。
ボットからすればもっと簡単で、 公開バンドルに匿名キーもAPIのURLも書いてあるんだから、 ページを開くことすらせず、外部サービスのAPIに直POSTすればいい。 どのみちサイトのドメインは通らない。
私が描いていた構成図は、間違ったドアの前に警備員を立てる図でした。 恥ずかしいことに、その図を「完成」だと思いかけていました。
じゃあCloudflareは要らないのか、というと違う
ここが大事なところで、 「Cloudflareは無駄だった」という話にはなりません。
玄関(サイト本体)にだって、別の客は来ます。 無差別のDDoS、脆弱性スキャナ、行儀の悪いクローラ。 それにドメイン全体で見れば、TLSの管理も、DNSSECも、 バラバラの登録業者に散らばった設定を1か所に集約できる。
ドメイン全体の防御・運用の標準化としては、Cloudflareを入れる価値は普通にあります。
ただ、それは別の病気の薬なんです。 「フォームスパム」という症状に、「ドメイン防御」という薬を出していた。 効かないのは薬が悪いからじゃなくて、病気が違うから。
本当の薬は、入口と同じ場所に置く
スパムの入口がその外部サービスなら、対策もそこに合わせる。 段階でこうなります。
まず気休めだけど効く層。 フォームにハニーポット(人間には見えない罠フィールド。埋まってたらボット)と、 時間トラップ(表示から送信までが速すぎる=人間じゃない、をフラグにする)を仕込む。 素朴なボットはこれで大半が落ちます。ブロックせず「スパム臭い」印だけ付けて、人間が拾えるようにするのがコツ。
本気で止めるなら、構造を変える。 ブラウザから直接データベースに書かせるのをやめて、 一度自前の検証エンドポイントを経由させる。 そこで人間確認(Turnstileのようなトークン)を検証してから書き込む。 そして匿名キーの直接書き込み権限は、剥奪する。
このとき初めて、その検証エンドポイントは自分のドメイン上に立つので、 さっきのCloudflareのWAFやレート制限が、ようやくフォームの通信にも効くようになる。 玄関を通る設計に変えたから、玄関の警備員が仕事をする。順番が逆だっただけ。
学び
防御は「どんな機能を足すか」で決まると思いがちですが、実際は違いました。 その通信が、どのホストに向かって飛んでいるかで決まる。
立派な箱(WAF、Bot対策)を持っていても、 守りたいトラフィックがその箱を通らないなら、素通りされて終わりです。
Cloudflareは玄関に立てられる。でも、スパムがどのドアから入ってくるかは、フォームの実装が決めている。
フォームひとつ直すときでも、 「送信ボタンを押したら、その通信はどこへ飛ぶのか」を先に見る。 構成図はそのあとで描く。
反射で処方箋を出しかけた自分への戒めとして、ここに置いておきます。 皆様も、フォームのスパム対策を頼まれたら、まず開発者ツールのNetworkタブを開いてください。 その通信、本当にあなたのサーバに来てますか?