APIセキュリティ - 安全なAPI設計と実装

9分 で読める | 2025.01.10

公式ドキュメント

最初に守ること:認証より認可

APIセキュリティでは、ログイン済みかだけでなく、その利用者が、そのデータと操作を実行してよいかをサーバー側で毎回確認します。 OWASP API Security Top 10でも、オブジェクト単位の認可不備(BOLA)は重要なリスクです。

APIのRequestを認証、object IDの認可、actionの認可、処理の順に進め、login済みでも任意IDへaccessさせない流れの図

悪い例: /api/orders/123 の 123 を受け取り、その注文を返す
必要な確認: 注文123の所有者または許可された役割が、現在の利用者か確認してから返す

画面でボタンを隠すだけでは認可になりません。URL、ID、役割、公開してよい項目をAPI側で検証します。

認証トークンを安全に扱う

トークンを受け入れる時は、署名、発行者、対象者、期限、用途を確認します。JWTのペイロードを秘密情報として扱わず、ログにもトークン全体を残しません。パスワード再設定やログイン試行は、通常のAPI以上にブルートフォース対策と監視が必要です。

入力と出力を別々に検証する

  • 入力は型、長さ、形式、許可値をサーバーで検証する
  • 更新できる項目を明示し、受け取ったJSONをそのまま保存しない
  • 出力は利用者の権限ごとに必要な項目だけ返す
  • URLを取得する機能は、内部ネットワークへのアクセス(SSRF)を防ぐ設計にする

SQLは文字列結合ではなく、使用するDBドライバやORMのパラメータ化されたクエリを使います。

レート制限は保護策の一つ

レート制限は、ログイン、パスワード再設定、注文、投稿など、濫用されると損害が大きい操作に適用します。利用者ID、APIキー、または信頼できるプロキシから渡されたIPを識別子にし、拒否時は429 Too Many Requestsを返します。

実装は利用するプラットフォームで異なります。次は特定SDKに依存しない疑似コードです。

key = authenticatedUserId ?? trustedClientIp(request)
result = rateLimiter.check("password-reset:" + key)

if result.allowed is false:
  return 429 with Retry-After when result.resetTime is known

continue the request

プロキシ構成を確認せずにX-Forwarded-Forを信頼すると、利用者が値を偽装できることがあります。分散型の制限では、障害時に拒否するか通すかも決めます。Upstashを使う場合は、現在のSDKでratelimit.limit(identifier)が返すsuccessremainingresetを扱います。

ログと監査

監査には、誰がいつどの操作をしたか、結果、対象の識別子を残します。一方で、パスワード、認証ヘッダー、アクセストークン、個人情報をログに含めません。異常な失敗率や認可失敗を観測できるようにします。

リリース前の確認

  1. 他人のIDへ差し替えても、データを読んだり更新したりできないか
  2. 権限のない項目を入力・出力できないか
  3. 期限切れ、別発行者、別用途のトークンを拒否するか
  4. 敏感な操作にレート制限、監視、復旧手順があるか
  5. エラーやログから秘密情報を取得できないか

まとめ

APIを安全にする中心は、サーバー側の認可です。認証、入力検証、出力の絞り込み、レート制限、監査を重ね、利用者が送る値や画面の表示だけを信頼しない設計にします。

参考リソース

関連記事

← 一覧に戻る
PR
PR
PR
PR