【入門編】APIレート制限(Rate Limiting)の実装によるブルートフォース攻撃対策 – アプリケーションセキュリティ & 安全な開発防御ガイド

玄関の鍵を1秒に100回ガチャガチャされたら?APIレート制限で守る「システムの治安」

こんにちは。セキュリティの現場で日々、防御の最前線に立っている者です。

今日は、開発者なら必ず一度は耳にする「レート制限(Rate Limiting)」についてお話しします。「難しそうだな…」と身構える必要はありません。まずは身近な「家の防犯」からイメージしてみましょう。

1. なぜ「レート制限」が必要なのか?(泥棒の視点)

あなたが家に住んでいると想像してください。頑丈な玄関ドアと鍵がありますよね。泥棒がその家を狙うとき、どうやって侵入するでしょうか?

窓を割るような派手な方法もありますが、一番手っ取り早いのは「ありとあらゆる鍵のパターンを片っ端から試すこと」です。これをITの世界ではブルートフォース攻撃(総当たり攻撃)と呼びます。

もし、泥棒が1秒間に100回もの猛スピードで鍵をガチャガチャと回し続けたらどうなるでしょう?どんなに頑丈な鍵でも、いつかは開いてしまいますよね。それに、あまりの騒がしさに家主(サーバー)は他の作業ができなくなり、ノイローゼになって倒れてしまいます。これがDoS攻撃(サービス拒否攻撃)です。

レート制限とは、「1分間に鍵を回せるのは最大でも3回まで!」と決めてしまう防犯ルールのことなんです。

2. 実装のキモ:Redisを使った「門番」の配置

では、開発現場ではどうやってこの「門番」を配置するのでしょうか。
一番シンプルで強力な方法は、Redisという超高速なデータ置き場を使うことです。

なぜRedisを使うのか? それは「今、この人は何回鍵を回したか?」という情報を、ミリ秒単位で確認できるスピードが必要だからです。

実装のイメージ(擬似コード)

例えば、ユーザーIDごとに「1分間に10回までしかAPIを叩かせない」というルールを作るなら、こんな流れになります。

import redis

Redisサーバーに接続
r = redis.Redis(host=’localhost’, port=6379, db=0)

def check_rate_limit(user_id):
key = f”rate_limit:{user_id}”

# 呼び出し回数をカウントアップ
current_count = r.incr(key)

# 初回アクセスなら、有効期限(1分=60秒)を設定
if current_count == 1:
r.expire(key, 60)

# 10回を超えていたら「拒否」
if current_count > 10:
return False # 門前払い!

return True # 通過OK

この仕組みがあれば、攻撃者がいくら猛スピードでリクエストを送ってきても、11回目からはサーバーが「もう今日は終わりですよ」と門前払いをしてくれるようになります。

3. レスポンスヘッダーで「優しさ」を伝える

レート制限をかけるとき、ただエラー(HTTP 429 Too Many Requests)を返すだけでは、ユーザーに対して少し不親切です。

「あとどれくらい待てばいいの?」という情報を、レスポンスヘッダーを使って親切に伝えてあげましょう。

  • `X-RateLimit-Limit`: 制限の合計回数
  • `X-RateLimit-Remaining`: 残り回数
  • `Retry-After`: 次にアクセス可能になるまでの待ち時間(秒)

これらをAPIの戻り値に含めておくことで、正常なユーザー(アプリなど)は「おっと、ちょっとリクエストを控えて待とう」と、自動的に賢い挙動をしてくれるようになります。

4. 盲点:IPアドレスだけで制限してはいけない?

初心者の方が陥りやすい罠があります。「IPアドレスだけで制限すればいいよね?」という考えです。

確かにIPアドレスによる制限は基本ですが、これには弱点があります。例えば、大きなオフィスや学校のWi-Fiを使っている人たちは、全員が「同じIPアドレス」を共有しています。一人が悪さをしたせいで、そのWi-Fiを使っている全員が巻き添えを食ってAPIを使えなくなるという悲劇が起こるのです。

防御のベストプラクティス

1. IPアドレス+ユーザーID(または認証トークン)の組み合わせで制限をかける。
2. ログイン前ならIPで制限し、ログイン後ならユーザーIDで制限を切り替える。
3. 重たい処理(検索やファイルアップロードなど)には、より厳しめの制限を設ける。

最後に:セキュリティは「いたちごっこ」を楽しむもの

セキュリティの対策に「これさえやれば絶対安心」という魔法はありません。でも、レート制限という「門番」を置くだけで、泥棒があなたのシステムを攻撃するコストは跳ね上がります。

「面倒くさい相手だな」と攻撃者に思わせたら、こちらの勝ちです。

まずは小さなプロジェクトから、Redisを使ったカウント制限を試してみてください。自分の書いたコードがシステムを守る「盾」になる瞬間、きっとエンジニアとしての面白さを感じてもらえるはずですよ。

それでは、また次回の記事でお会いしましょう!安全な開発ライフを!

コメント

タイトルとURLをコピーしました