結論から
ブルートフォース(総当たり)攻撃は、ログイン画面にパスワードを機械で何万回も試す攻撃です。派生形の「リスト型攻撃(クレデンシャルスタッフィング)」は、他のサービスから漏れたメールとパスワードの組を、あなたのアプリに片っ端から試します。2025年6月には、情報窃取マルウェアの記録などを寄せ集めた 約160億件のログイン情報が公開状態で見つかりました。攻撃者の手元には、試す材料がいくらでもあります。
この記事で伝えたいのは、この一点だけです。ログイン画面は「何回でも試せる」なら、いつか当たる。回数と速度に上限を付ける(レート制限)のがサーバーの仕事で、AI は頼まれない限り付けない。 上限は、ログイン・パスワードリセット・ワンタイムコード(OTP)・API の4か所に要ります。
- 何が起きるか:攻撃者のプログラムが、1秒に数十回、ログインを試す。パスワードが「password123」「会社名2024」なら、数分で入られる。6桁のワンタイムコードは、100万通りしかない。上限が無ければ数時間で当たる
- なぜ:サーバーは、同じ人(IP・アカウント)から何回来ても、毎回まじめに答える。「5回間違えたら15分待たせる」という1行が無いから
- 直す:ログイン・リセット・OTP・API にレート制限(回数と時間の上限)。認証サービス(Supabase / Firebase / Clerk)の組み込み制限を確認。CAPTCHA は補助。エラーメッセージで「メールが存在しない」と教えない
- 確かめる:自分のログイン画面で、わざと間違ったパスワードを20回連続で入れる。20回目も普通に「パスワードが違います」と返ってくるなら ✗
動画版(約2分半)は本文の上に埋め込んであります。
① 何が起きるのか:1秒に数十回、「試す」
例として、AIで作った予約アプリのログイン画面があるとします。メールとパスワードを入れて、合っていれば入れる。間違っていれば「パスワードが違います」。ここまでは正常です。
では、攻撃者がプログラムで、同じメールに対してパスワードを1秒に30回試したら。
password → 違います。password1 → 違います。Password123 → 違います。……1時間で10万回。よくあるパスワードの上位10万件は、公開されたリストがあります。佐藤さんのパスワードがその中にあれば、1時間以内に入られます。
もう1つの形がリスト型攻撃です。攻撃者は「他のサービスから漏れたメール+パスワード」の一覧を持っています。2025年6月、そうしたデータを寄せ集めた約160億件分が公開状態で見つかりました。多くの人はパスワードを使い回すので、あなたのアプリで1回ずつ試すだけで、一定の割合で入れます。1件ずつ、1回ずつなので「同じアカウントに何回も失敗」という形にはなりません。
そして、見落とされがちなのがワンタイムコード(OTP)です。SMS やメールで届く6桁の数字は、100万通りしかありません。「コードを入力」の画面に上限が無ければ、プログラムは全部試せます。
② なぜ起きるのか:サーバーは「何回でも」まじめに答える
原因は、サーバーに「回数を数える」処理が無いことです。サーバーは、同じ IP アドレス・同じアカウントから何回リクエストが来ても、毎回まじめに「違います」と返します。人間は1分に5回しか試しませんが、プログラムは1秒に数十回試せる。この差を埋めるのがレート制限です。
レート制限とは、「同じアカウント(または同じ IP)から、一定時間に一定回数を超えたら、しばらく受け付けない」という仕組みです。「5回失敗したら15分待たせる」「1 IP から1分に10回まで」のように書きます。総当たりは「1時間で10万回」が前提なので、1分に5回に制限されると、10万回に14日かかります。 それだけで、攻撃として成り立たなくなります。
AI はどう書くか。 「ログイン機能を付けて」で作られるのは、メールとパスワードの照合まで。レート制限は「動作に必要ない」ので、頼まれない限り入りません。一方、Supabase Auth・Firebase Auth・Clerk・Auth0 などの認証サービスには、ログインの試行制限が最初から組み込まれています(Supabase は Auth → Rate Limits で設定値が見られます)。だから、認証サービスを使っていれば、ログイン画面はだいたい守られています。
危ないのは、AI が自前で作った部分です。「パスワードリセット」「OTP の照合」「API キーの照合」「問い合わせフォーム」など、認証サービスの外にある入口。ここには制限がありません。特に、AI が「ワンタイムコードでログインできるようにして」と頼まれて自前で6桁を発行・照合するコードを書いた場合、上限がなければ最も弱い入口になります。
さらに、エラーメッセージにも落とし穴があります。「そのメールアドレスは登録されていません」と返すと、攻撃者は「どのメールが有効か」を先に選別できます。「メールまたはパスワードが違います」と、区別せずに返すのが定石です。
③ どう直すのか:AIに「4か所にレート制限」を頼む
以下をそのまま AI ツールに貼ってください。
「このプロジェクトで、①ログイン、②パスワードリセット(メール送信と、リセットの実行)、③ワンタイムコードや確認コードの照合、④認証が要らない API や問い合わせフォーム、のそれぞれについて、レート制限(同一アカウント・同一 IP からの一定時間内の回数上限)があるか確認してください。認証サービス(Supabase / Firebase / Clerk 等)の組み込み制限に頼っている箇所は、その設定値を示してください。制限が無い箇所には、『同一アカウントで5回失敗したら15分ロック』『同一 IP で1分に10回まで』を目安に追加してください。ワンタイムコードは、5回失敗でコードを無効化してください。あわせて、ログイン失敗時のメッセージが『メールが存在しない』と『パスワードが違う』を区別していないか確認してください。」
ポイントは、「4か所」を列挙して聞くこと。「ログインにレート制限を付けて」だけだと、リセットと OTP が残ります。
④ 直ったかを確かめる:わざと20回、間違える
- 自分のログイン画面で、正しいメール+間違ったパスワードを20回連続で入れる。途中で「しばらく待ってください」「429」が出れば ◯。20回目も普通に「違います」なら ✗
- パスワードリセットを、同じメールで10回連続で依頼する。10通届くなら ✗(メール爆撃にも使われる)
- OTP の画面で、間違ったコードを10回入れる。10回目も受け付けるなら ✗
- 存在しないメールでログインし、「登録されていません」と出たら、メッセージを直す
- 認証サービスを使っているなら、管理画面の Rate Limits の設定値を1度見ておく
- 分からなければ、AIに「同一アカウントで6回連続ログイン失敗したときに 429 が返ることを確認するテストを書いて」
自分で直せないとき:エンジニアに送る一文
「ログイン・パスワードリセット・ワンタイムコードの照合に回数制限がありません(20回連続で失敗しても止まりません)。レート制限の追加と、認証サービスの組み込み制限の設定確認をお願いします。」
よくある質問
パスワードを長く・複雑にするよう強制すれば、防げますか。
総当たりには効きますが、リスト型攻撃(漏れたパスワードの使い回し)には効きません。どんなに複雑でも、他サービスで漏れていれば1回で当たります。だからレート制限と、できれば2段階認証を組み合わせます。
CAPTCHA(「私はロボットではありません」)を付ければいいですか。
補助にはなります。ただ、CAPTCHA を突破するサービスも存在し、ユーザーの手間も増えます。まずレート制限、次に CAPTCHA、の順です。
Supabase を使っています。何もしなくていいですか。
ログインとサインアップは組み込みの制限があります。ただし、AI が自前で作ったパスワードリセット画面や OTP 照合、認証不要の API は、制限の外です。③のプロンプトで「4か所」を確認してください。
この穴が塞がれば、ログインは安全ですか。
「当てられる」ことは防げます。「盗まれる」(→ セッションハイジャックの記事)、「そもそも誰でも入れる」(→ 認証と認可の記事)は別の話です。ログイン周りは、この3本セットで確認してください。


