【実務・中級編】 APIゲートウェイにおける認証・認可とレート制限 – インフラ・ネットワーク & クラウドセキュリティ防御ガイド

現場のエンジニア諸君。セキュリティ対策というと、多くの人間が「何を入れれば安全になるか」という足し算の思考に陥る。だが、真の要塞化とは「攻撃の入り口を絞り込み、許容できる境界を極限まで硬化させる」引き算の哲学だ。

今日はAPIゲートウェイにおける認証・認可とレート制限について、教科書の綺麗事ではなく、泥臭い戦場での実戦論を話そう。

1. なぜ「認証」だけではインフラが死ぬのか

多くの開発者が、認証(OAuth2/OIDC)さえ通せばAPIは安全だと勘違いしている。甘い。認証済みユーザーが悪意あるスクリプトを回したり、あるいは認証エンドポイント自体がブルートフォースの標的になった場合、バックエンドのDBは一瞬でダウンする。

攻撃者は、認証を突破しようとするのではなく、「認証処理という重いタスクを大量に投げつけて、システムのリソースを枯渇させる(DoS)」ことを狙う。これがAPIゲートウェイでレート制限が必須である最大の理由だ。

2. APIゲートウェイで実装すべき「盾」:Nginx設定

WAFを入れるのは大前提だが、その手前のNginxで「壊される前に弾く」設定を叩き込んでおく必要がある。以下の設定は、IP単位でのリクエスト制限と、バースト時の制御を行う実戦的なテンプレートだ。

# nginx.conf の http コンテキストに記述
# 1分間に20リクエストまで。それ以上は遅延させ、50リクエストを超えたら即断(503)
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=20r/m;

server {
    listen 443 ssl;
    server_name api.example.com;

    location /api/ {
        # レート制限を適用(burstは許容バースト数、nodelayで即時判定)
        limit_req zone=api_limit burst=10 nodelay;
        
        # 認可ヘッダーがないリクエストは門前払い
        if ($http_authorization = "") {
            return 401;
        }

        proxy_pass http://backend_cluster;
    }
}

この設定の肝は nodelay だ。これを入れないと、攻撃者は「遅延したレスポンス」を待つ間にTCPコネクションを大量に占有してしまう。即座に「429 Too Many Requests」を返して接続を切るのが、インフラを守るための正しい冷徹さだ。

3. アプリケーション層での認可:Python (FastAPI) での防御

認証済みIDが「誰のリソースにアクセスできるか」という認可(RBAC/ABAC)の不備は、水平権限昇格攻撃(他人のデータを閲覧する攻撃)を招く。認証トークン(JWT)を検証し、リソースオーナーシップを厳格にチェックするコード例を示そう。

from fastapi import FastAPI, Depends, HTTPException, Header

app = FastAPI()

def verify_token(authorization: str = Header(...)):
    # ここでJWTの署名検証と有効期限チェックを行う(ライブラリ推奨: PyJWT)
    # 偽造トークンであれば即座に例外を投げる
    if not authorization.startswith("Bearer "):
        raise HTTPException(status_code=401, detail="Invalid token format")
    return {"user_id": "12345"} # 検証後のユーザーID

@app.get("/user/profile/{target_user_id}")
async def get_profile(target_user_id: str, user=Depends(verify_token)):
    # 最も重要なチェック:トークンの持ち主と、リクエスト対象が一致するか
    # ここを怠ると、URLパラメータを書き換えるだけで他人の個人情報が抜かれる
    if user["user_id"] != target_user_id:
        raise HTTPException(status_code=403, detail="Permission Denied")
    
    return {"data": "セキュアな個人情報"}

4. 最後に:エンジニアが守るべき「境界」の意識

コードを書いて終わりではない。以下の3点を、明日の朝から運用に組み込んでほしい。

1. レート制限のログを可視化せよ: 429エラーが急増している時は、攻撃の予兆か、あるいはデプロイしたバグがループしているかだ。これを監視していないのは、目隠しをして夜道を歩いているのと同じだ。
2. JWTは「信じるな」: APIゲートウェイで検証したからといって、バックエンドで再検証をサボるな。多層防御こそが、万が一ゲートウェイが突破された時の最後の砦になる。
3. 不要なメソッドは殺せ: TRACEやOPTIONSなど、APIで不要なHTTPメソッドはNginx側で deny all してしまえ。攻撃者はそこからサーバーの挙動を探ってくる。

セキュリティは「完成」しない。だが、攻撃者が「このシステムを攻略するのはコストに合わない」と判断してターゲットを外すレベルまで引き上げることは可能だ。

君たちの書くコードが、システムの最後の防波堤になる。誇りを持って、堅牢な設計を続けてくれ。何か不明点があれば、またいつでも聞いてくれ。

コメント

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