セキュリティ対策
レート制限と濫用対策 — 「回数を絞る」だけでは、総当りもコスト暴走も止まらない
レート制限は『速さを絞る』話ではなく『誰を・何を・いくらまで数えるか』の設計です。NISTは連続失敗を100回までに制限せよと定める一方、厳しすぎるロックアウトが正規利用者へのDoSになると警告します。OWASPはAPIの上限に支出上限を含めています。ログイン総当り・確認メール爆撃・公開AIエンドポイントの課金暴走を、一次情報にもとづいて設計で止める方法。
レート制限がうまくいかないのは、たいてい「緩すぎた」からではありません。問いの立て方を間違えたからです。「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回あたりの期待利得(当たる確率、当たったときに通る度合い)を下げる。成功確率をゼロにできなくても、割に合わなくすれば攻撃は止まります。
だから当サイトは、厳しいロックアウトより、遅延と多要素の組み合わせを勧めます。そして守る対象がお金であるときだけは話が別で、唯一の確実な上限は、自分のコードの外側にある支出上限です。コードは間違えます——間違えても金額が青天井にならない層を、必ず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(上限を設けるべき資源の列挙、コスト面の影響、サードパーティ支出上限の設定)
次に読む
- 前提: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回あたりのコストが大きい処理を防げません。プロバイダ側の支出上限を必ず設定してください——これはアプリのバグでも止まらない、最後の砦です。