レート制限がうまくいかないのは、たいてい「緩すぎた」からではありません。問いの立て方を間違えたからです。「1分間に何回まで」を決める前に、答えるべき問いが3つあります。誰を数えるのか。何を数えるのか。上限に達したらどうするのか。
問い①:誰を数えるのか
IPを主軸にすると、攻撃者側と正規利用者側の両方で問題が起きます
攻撃者側:リバースプロキシやCDNの背後では、アプリが見ている送信元IPはヘッダに書かれた値であることがあります。X-Forwarded-For を無条件に信用すると、ヘッダを付け替えるだけで別人として数えられる。数えているつもりで、何も数えられていない状態です。どこまで信用してよいかは X-Forwarded-For 偽装と信頼できるプロキシ にまとめています。
正規利用者側:企業のNATやモバイル回線では、無関係な多数の利用者が同じIPを共有します。IP単位で制限すると、攻撃者ではない人が巻き込まれます。
だから主軸は「行為の主体に紐づく識別子」(アカウント、APIキー、確認済みのセッション)に置き、IPは補助的な信号として重ねます。未認証の段階(ログイン前)では主体を特定できないので、そこは次の問いで補います。
問い②:何を数えるのか
回数だけを数える設計は、1回が重い処理を止められません。OWASP の API Security Top 10 は API4:2023「Unrestricted Resource Consumption」 で、上限を設けるべき対象を具体的に列挙しています。
数えているもの
リクエスト数:100/分 → 上限内 ✓
↓ しかし実際に消費されているのは
CPU・時間
1回で全件走査
メモリ
巨大な入力
帯域
1万件返す
お金
従量課金APIを連打
= 上限に触れないまま枯渇する
- 実行時間・メモリ
- 実行タイムアウト、最大メモリ割り当て
- OSの資源
- ファイルディスクリプタ数、プロセス数
- 入力の大きさ
- アップロードファイルの最大サイズ、入力パラメータの最大サイズ
- 1リクエストの仕事量
- 1回のAPIリクエストで実行する操作の数、1ページあたりに返すレコード数
- お金
- サードパーティプロバイダーの支出上限(後述。金銭被害を止める最後の対策です)
「1分100リクエストまで」を守っていても、1リクエストで1万件返す/巨大なファイルを処理する/外部の従量課金APIを何度も呼ぶなら、資源も請求も守れていません。数える単位を、守りたいもの(CPU・メモリ・帯域・お金)に合わせる。これが設計の要点です。
問い③:上限に達したら、どうするのか
ここが最も誤解されている部分です。「厳しくすればするほど安全」ではありません。
単純なロックアウトの副作用
「3回失敗でアカウント凍結」は直感的ですが、攻撃者が他人のアカウントを意図的に凍結させられます。つまり正規利用者へのサービス妨害の道具になります。総当りを止める代わりに、締め出しを攻撃手段として提供してしまう。
「割に合わなくする」設計
止めるのではなく試行の速度を落とす。NIST SP 800-63B が挙げている工夫は、CAPTCHAの要求、失敗回数が上限に近づくほど長くなる待ち時間、過去に認証成功したIPの許可リスト、そしてリスクベース/適応型認証(IPアドレス、地理的位置、時間帯、ブラウザのメタデータなどから通常の振る舞いかを判断する)です。
NISTの数字は意外に大きい:連続失敗「100回まで」
NIST SP 800-63B は「検証者は、単一アカウントに対する連続した認証失敗を100回以下に制限しなければならない(SHALL)」と定めています。よく見かける「3回でロック」は規格の要求ではありません。
なぜ100回で足りるのか。遅延とCAPTCHAが入れば、100回に到達するまでの時間が現実的でなくなるからです。逆に言えば、回数だけを厳しくして遅延を入れない設計は、最も良くない(正規利用者を締め出しつつ、自動化された攻撃には短時間で試行を許す)。
もう1つ実務的な指針として、同文書は「認証に成功したら、同一IPからのそれ以前の失敗は無視してよい(SHOULD)」としています。カウンタをいつリセットするかまで設計に含めてください。
場面別:どこに、何を掛けるか
ログイン(総当り・パスワードリスト攻撃)
アカウント単位の失敗カウンタを主軸に、遅延を段階的に伸ばす。IPは補助信号として使い、単独の根拠にしない。多要素認証を入れれば、パスワードが当たっても即座には通らないため、総当りが割に合わなくなります。なお近年の侵入は、破るのではなく正規の認証情報を持って入る型が主流です(2026年の侵入経路の横断分析)。レート制限は必要条件であって十分条件ではありません。
パスワードリセット・確認メール(メール爆撃)
送信をトリガーできる条件と同一宛先への送信数の両方を数えます。フォームに他人のアドレスを入れられる設計は、第三者への嫌がらせと自社ドメインの送信評価の低下を同時に招きます。宛先単位のクールダウン、再送間隔、そして未確認のまま放置されたレコードの削除(保持する未検証の個人情報を減らす)を組み合わせてください。リセット経路そのものの設計は パスワードリセットの設計欠陥 に詳しくまとめています。
公開エンドポイント/AI機能(コストの急増)
リクエスト数ではなくコストを数えます。 1回あたりの入力サイズに上限を設け、1リクエストで行う操作数を制限し、プロバイダ側の支出上限を必ず設定する。OWASPが挙げる想定シナリオには、月13ドルだった請求が8,000ドルに膨らむ例があります。従量課金の外部APIを公開機能に繋ぐときは、アプリにバグがあっても機能する仕組み(プロバイダ側の上限)を必ず用意してください。鍵が漏れた場合に何が起きるかは 盗まれたキーで請求とアカウント停止が起きた話 と AIで書いたコードからAPIキーが漏れた——本当の原因 にまとめています。
重い処理(検索・エクスポート・ファイル処理)
実行時間、メモリ、アップロードサイズ、1ページあたりの返却件数に明示的な上限を置きます。上限が無い箇所は、1リクエストで資源を使い切られる原因になります。コンテナやサーバーレスの側でもメモリ・CPU・プロセス数を制限し、アプリが想定外に資源を使っても外側で止まる構成にしてください。
上限に達したことを、あなたが知る
制限は掛けただけでは半分です。上限に到達している事実が誰にも見えないなら、攻撃が進行中でも、正規利用者が締め出されていても気づけません。到達回数を記録し、急増したら通知する。組織のセキュリティ基準で言うところの「異常に気づける状態」を、ここでも作ります。
当サイトの視点:制限の目的は、攻撃を割に合わなくすること
レート制限を攻撃を完全に防ぐ仕組みと考えると、必ず「何回までなら安全か」という答えの出ない問いに行き着きます。当サイトの見方は違います。これは攻撃者にとっての費用と利得の設計です。攻撃者にとっての1回あたりの費用(時間・計算・CAPTCHA・追加要素)を上げ、1回あたりの期待利得(当たる確率、当たったときに通る度合い)を下げる。成功確率をゼロにできなくても、割に合わなくすれば攻撃は止まります。
だから当サイトは、厳しいロックアウトより、遅延と多要素の組み合わせを勧めます。そして守る対象がお金であるときだけは話が別で、唯一の確実な上限は、自分のコードの外側にある支出上限です。コードは間違えます。間違えても金額が際限なく増えない仕組みを、必ずコードの外側に置いてください。
出典(一次情報)
- NIST SP 800-63B「Digital Identity Guidelines: Authentication and Lifecycle Management」§5.2.2 Rate Limiting (Throttling) — pages.nist.gov(連続失敗100回以下のSHALL要件、CAPTCHA・逓増する待ち時間・IP許可リスト・リスクベース認証、成功時に同一IPの過去失敗を無視してよいSHOULD)
- OWASP API Security Top 10 2023「API4:2023 Unrestricted Resource Consumption」 — owasp.org(上限を設けるべき資源の列挙、コスト面の影響、サードパーティ支出上限の設定)
次に読む
- 2026年の大型事案の比較:KDDI・アフラック・デジタル庁・さくらインターネットに共通する教訓
- 実例:デンマークの住民登録(CPR)への不正な照会(正規の取引先の照会権限が悪用された事案)
- 実例:バイトルの不正アクセス(最大388万件のメールアドレス)(「仕様の不備」を突いた大量取得と、件数の上限)
- 前提:X-Forwarded-For 偽装と信頼できるプロキシ(「誰を数えるか」の前提)
- 設計:パスワードリセットの設計欠陥 / 多要素認証の選び方
- コスト:盗まれたキーで請求とアカウント停止が起きた話 / AIで書いたコードからAPIキーが漏れた
よくある質問
Qログイン失敗は何回で止めるべきですか? 3回や5回でロックすべき?
NIST SP 800-63B は『検証者は単一アカウントに対する連続した認証失敗を100回以下に制限しなければならない』と定めています。3回や5回という数字は規格の要求ではありません。むしろ同文書は、正規利用者を締め出さないための工夫としてCAPTCHA、失敗回数が上限に近づくほど長くなる待ち時間、過去に成功したIPの許可リスト、リスクベース認証を挙げています。厳しいロックアウトは、攻撃者が他人のアカウントを意図的に凍結させる道具にもなります。上限だけを厳しくするのではなく、遅延と追加要素で『割に合わなくする』のが設計の要点です。
QIPアドレス単位でレート制限すれば十分ですか?
不十分です。まず、リバースプロキシやCDNの背後では、アプリが見ているIPが実際の送信元とは限りません。X-Forwarded-For を無条件に信用すると、ヘッダを付け替えるだけで制限を回避されます(誰を数えているのか分からなくなる)。次に、正規利用者も企業NATやモバイル回線で同じIPを共有するため、IP単位の制限は無関係な利用者まで制限してしまいます。アカウント単位・APIキー単位・セッション単位など、行為の主体に紐づく識別子を主軸にし、IPは補助的な信号として扱ってください。
Q確認メールの大量送信(メール爆撃)はどう防ぎますか?
『送信をトリガーできるのは誰か』を絞ることと、『同じ宛先に何通まで送るか』を数えることの両方が要ります。フォームに他人のアドレスを入力できる設計では、攻撃者は第三者への嫌がらせに使えますし、自社のドメインが送信元として評価を落とします。宛先アドレス単位のクールダウン、同一アドレスへの再送間隔、未確認のまま一定時間が過ぎたレコードの削除(保持する未検証の個人情報を減らす)を組み合わせてください。
QAIのAPIを公開機能に組み込むとき、いちばん危ないのは何ですか?
請求です。OWASPのAPI Security Top 10 は API4:2023「Unrestricted Resource Consumption」で、制限すべき対象に実行時間・メモリ・アップロードサイズ・1リクエストあたりの操作数などと並べて『サードパーティプロバイダーの支出上限』を明記しています。同項の想定シナリオには、月13ドルだった請求が8,000ドルに膨らむ例が挙げられています。リクエスト数の制限だけでは、1回あたりのコストが大きい処理を防げません。プロバイダ側の支出上限を必ず設定してください。アプリにバグがあっても機能する、最後の対策です。