Vol.07 API開発時に気をつけるべきセキュリティの基本
- atsu wada
- 4月17日
- 読了時間: 13分

この記事であなたがやるべきこと
後述する「API開発におけるセキュリティ対策の5つの基本」を理解して、
自分が開発するAPIに適切なセキュリティ対策を取り入れ、
脆弱性のない安全なAPIを設計・実装できるようになること
はじめに

「APIはバックエンドだから、フロントエンドほどセキュリティを気にしなくていいよね?」
こう考えていませんか?実は、APIはシステムの「入口」となる重要な部分であり、セキュリティリスクが特に高い領域です。特に近年では、マイクロサービスアーキテクチャの普及により、APIの重要性は一層高まっています。
しかし、APIのセキュリティ対策が不十分だと、データの漏洩や不正アクセス、サービスの停止など、深刻な被害をもたらす可能性があります。「動けば良い」という考えだけでAPIを開発してしまうと、後からセキュリティホールを塞ぐのに多大な時間とコストがかかります。
この記事では、API開発時に気をつけるべきセキュリティの基本を解説します。新卒エンジニアでも理解しやすいよう、具体的な実装例とともに説明していきますので、日々の開発業務にすぐに活かせるはずです。
なぜAPIのセキュリティ対策が重要なのか?

APIはシステム間の通信の要であり、外部からのアクセスポイントとなるため、セキュリティ上の弱点が存在すると重大な被害をもたらします。以下で説明する「APIの特性とリスク」や「実際に起きた事例」から分かるように、適切な対策を怠ると、データ漏洩や不正アクセスといった深刻な問題につながる可能性があります。
APIの特性とリスク
APIは、異なるシステム間でデータをやり取りするための「窓口」です。この窓口が適切に保護されていないと、以下のようなリスクが生じます。
代表的な例としては:
データの漏洩: 不適切なアクセス制御により、機密情報が第三者に漏れる
不正アクセス: 認証や認可の不備により、権限のないユーザーがデータにアクセスする
サービスの停止: 大量リクエストによるDoS攻撃で、サービスが利用できなくなる
データの改ざん: 入力値の検証不足により、不正なデータが登録される
実際に起きた事例
TrelloのAPI認証不備によるデータ漏洩(2024年)
Trelloでは、APIエンドポイントに適切な認証が設定されておらず、約1500万件のユーザーアカウント情報(メールアドレスなど)が流出する事件が発生しました。攻撃者はエンドポイントへのリクエストを操作し、大量のデータを収集。この事例は「適切な認証とアクセス制御」の欠如によるリスクを如実に示しています。より厳格な認証メカニズムと定期的なセキュリティ監査が実施されていれば防げた可能性が高いでしょう。
DellパートナーポータルのAPI脆弱性(2024年5月)
Dellではパートナーポータルに存在したAPI脆弱性により、4900万件もの顧客記録が流出する事件が発生しました。攻撃者はパートナーアカウントを取得後、サービスタグを自動生成して大量のリクエストを実行。レート制限や異常検知が欠如していたため、このような大規模な情報収集が可能になってしまいました。この事例は、APIに対する適切なレート制限と異常検知の重要性を浮き彫りにしています。
これらの事例から明らかなように、APIのセキュリティ対策は単なる理論上の懸念ではなく、実際のビジネスに直結する重大な問題です。適切な対策を講じなければ、企業の信頼性や財務に深刻な影響を及ぼす可能性があります。
API開発におけるセキュリティ対策の5つの基本

1. 適切な認証・認可の実装
何をすべきか:
安全な認証メカニズム(OAuth、JWT、APIキーなど)を導入する
認証だけでなく、認可(アクセス権限の確認)も徹底する
機密性の高いAPIには多要素認証を検討する
実装例(JWT認証 - Node.js + Expressの場合):
Spring Boot (Java) でのOAuth2実装例:
注意点:
トークンの有効期限を適切に設定する(長すぎると危険)
秘密鍵やAPIキーはソースコードに直接書かず、環境変数などで管理
OAuthの実装では、適切なスコープ設定と定期的なトークンの更新が重要
セッション管理を使用する場合は、CSRFトークンも忘れずに
2. 入力値の検証と出力のエスケープ
何をすべきか:
すべての入力パラメータをサーバーサイドで検証する
データ型、長さ、フォーマットなどを厳密にチェック
不正な入力を弾く(ホワイトリスト方式を優先)
SQLインジェクションやコマンドインジェクションの対策
実装例(入力検証 - Java + Spring Boot):
実装例(入力検証 - Node.js + Express + Joi):
SQLインジェクション対策の実装例:
注意点:
フロントエンドのバリデーションは利便性のためであり、セキュリティのためにはサーバーサイドでの検証が必須
バリデーションエラーメッセージは詳細すぎないように注意(攻撃の手がかりになる可能性)
入力検証に失敗した場合は、安全な値に変換するのではなく、基本的には処理を中止する
3. レート制限とリソース管理
何をすべきか:
APIへのリクエスト数を制限し、DoS攻撃から保護する
IPアドレス、APIキー、ユーザーIDなど適切な単位で制限を設ける
リクエストサイズやレスポンスサイズの上限を設定する
異常なトラフィックパターンを検知する仕組みを導入する式
実装例(レート制限 - Express + express-rate-limit):
実装例(レート制限 - Spring Boot + bucket4j):
注意点:
ユーザー体験とセキュリティのバランスを考慮したレート制限を設定
リソース集約的な操作(重いクエリ、大きなファイルのアップロードなど)には特に厳しい制限を設ける
レート制限に達した場合のエラーメッセージやステータスコード(429 Too Many Requests)を適切に設定
制限を超えた場合、再試行までの待機時間を伝えるとユーザー体験が向上する
4. 適切なエラーハンドリングとロギング

何をすべきか:
エラーメッセージから機密情報が漏れないようにする
本番環境では詳細なスタックトレースを表示しない
セキュリティ関連のイベントを適切にログに記録する
ログ自体からの情報漏洩を防ぐ(個人情報や認証情報など)
実装例(エラーハンドリング - Express):
実装例(セキュリティログ - Spring Boot):
注意点:
ログには機密情報(パスワード、トークン、個人情報など)を含めない
セキュリティ関連のログは長期保存を検討し、インシデント調査に備える
ログの改ざんを防ぐため、ログの一元管理やログサーバーへの転送を検討
ログレベルを適切に設定し、重要度に応じた対応ができるようにする
アクセス失敗のログは特に重要(不正アクセスの兆候を検知できる)
5. セキュアなHTTP設定とAPIドキュメント管理
何をすべきか:
すべての通信でHTTPSを強制する
セキュリティ強化のためのHTTPヘッダーを設定する(HSTS、CSPなど)
APIドキュメントの公開範囲を適切に管理する
機密情報をURLパラメータに含めない
実装例(Spring Security でのセキュアHTTPS設定):
APIドキュメント管理のベストプラクティス:
公開APIのドキュメントは公開しても問題ないが、内部APIのドキュメントは適切にアクセス制限する
APIドキュメントツール(Swagger/OpenAPIなど)の認証設定を適切に行う
機密情報(APIキー、トークン、パスワードなど)をドキュメント内に含めない
本番環境のURLやエンドポイント情報を不必要に公開しない
注意点:
HTTP Strict Transport Security (HSTS) の設定により、ブラウザはHTTPSでの通信を強制的に行うようになる
セキュリティヘッダーは追加するだけでなく、その意味と影響を理解することが重要
使用しないHTTPメソッド(TRACE、OPTIONSなど)は必要に応じて無効化を検討
WebサーバーレベルでもHTTPS設定とセキュリティヘッダーを適切に設定する
実装時によくある間違いと対策

1. 不正確な権限チェック
よくある間違い:
正しい実装:
2. 環境変数などの設定ミス
よくある間違い:
正しい実装:
3. デバッグ情報の漏洩
よくある間違い:
正しい実装:
今日からできる
API開発セキュリティチェックリスト

以下のチェックリストを使って、自分が開発するAPIのセキュリティを確認しましょう。
認証・認可
適切な認証メカニズム(JWT、OAuth2など)を実装している
すべてのAPIエンドポイントで適切な認可チェックを行っている
トークンは適切な有効期限を設定している
重要な操作には追加の認証を要求している
認証情報(APIキー、トークンなど)は安全に管理している
入力検証とデータ処理
すべての入力パラメータに対するサーバーサイドバリデーションを実装している
ホワイトリスト方式でのバリデーションを優先している
SQLインジェクション対策を実装している(ORM、プリペアドステートメントなど)
ファイルアップロード時のファイルタイプとサイズを検証している
JSONデータの解析時にサイズ制限を設けている
リクエスト管理
レート制限を実装している
特に認証、登録、パスワードリセットなどの重要なエンドポイントに厳しい制限を設けている
リクエストのサイズ制限を設定している
タイムアウト設定を適切に行っている
長時間実行される処理については非同期処理の実装を検討している
エラーハンドリングとロギング
本番環境では機密情報を含まないエラーメッセージを返している
セキュリティイベント(認証失敗、権限エラーなど)を適切にログに記録している
ログから機密情報(パスワード、トークンなど)を除外している
重要なAPIアクセスをログに記録している
ログの完全性を確保するための対策を講じている(一元管理など)
HTTPとTLS
すべてのAPIエンドポイントでHTTPSを強制している
適切なTLS設定を行っている(TLS 1.2以上、強力な暗号スイートなど)
セキュリティヘッダー(HSTS, CSP, X-Content-Type-Optionsなど)を設定している
CORSの設定を適切に行い、必要なドメインのみを許可している
APIのバージョン管理が適切に行われている
API仕様とドキュメント
機密情報をAPIドキュメントに含めていない
APIドキュメントへのアクセスを適切に制限している
エラーレスポンスが一貫した形式になっている
ステータスコードを適切に使用している(401、403、429など)
必要に応じてレスポンスにキャッシュ制御ヘッダーを設定している
よくある疑問(Q&A)

Q1: 社内向けのAPIでもセキュリティ対策は必要ですか?
A: はい、絶対に必要です。外部公開用APIだけでなく、社内向けAPIもセキュリティ対策を徹底すべきです。理由としては:
内部犯行のリスクがあります
一度内部ネットワークに侵入されると、セキュリティが不十分なAPIは格好の標的になります
将来的に外部連携が必要になった場合、セキュリティ設計の見直しに多大なコストがかかります
社内向けAPIだからといってセキュリティを軽視すると、「内部は信頼できる」という危険な前提に依存することになります。アクセス制御やTLS通信などの基本的なセキュリティ対策は、APIの公開範囲に関わらず実装すべきです。
Q2: API開発でセキュリティとパフォーマンスのバランスをどう取ればいいですか?
A: セキュリティとパフォーマンスは必ずしもトレードオフの関係ではありません。以下のポイントを考慮しましょう:
優先順位の明確化: データの機密性や重要性に応じて、セキュリティレベルを調整する
キャッシュ戦略: 認証や認可の結果をキャッシュし、毎回のチェックを効率化する
効率的な実装: 例えば、トークンベースの認証はセッション管理より効率的な場合がある
段階的な認証: 公開情報取得APIは軽い認証、重要操作APIは厳格な認証というように分ける
非同期処理: 重い処理は非同期で行い、APIのレスポンス速度を維持する
多くの場合、適切な設計を行えば、セキュリティとパフォーマンスの両立は可能です。また、セキュリティインシデントのコストと比較すれば、多少のパフォーマンスオーバーヘッドは許容できることが多いでしょう。
Q3: マイクロサービスアーキテクチャでのAPI間通信のセキュリティはどうすればいいですか?
A: マイクロサービス間の通信セキュリティには、以下のアプローチが有効です:
サービスメッシュの活用: Istio、Linkerdなどのサービスメッシュを導入し、通信の暗号化、認証、認可を一元管理
相互TLS (mTLS): クライアント側とサーバー側の両方で証明書による認証を行う
サービスアカウント: サービスごとに異なる認証情報(トークン)を発行し、最小権限の原則を適用
APIゲートウェイ: 外部からのリクエストを一元的に処理し、内部サービスへのアクセスを制御
ネットワークポリシー: Kubernetes NetworkPolicyなどを使用して、サービス間通信を制限
マイクロサービスでは「ゼロトラスト」の考え方が重要です。内部ネットワークであっても、すべてのサービス間通信に認証・認可を要求し、暗号化を行うことで、より堅牢なセキュリティを実現できます。
Q4: APIキーとJWTトークン、どちらを使うべきですか?
A: 用途によって最適な選択は異なります:
APIキーが適している場合:
サーバー間通信やバックエンドサービスからのアクセス
長期間有効な認証が必要な場合
シンプルな認証のみが必要で、詳細な権限管理が不要な場合
JWTトークンが適している場合:
ユーザー認証が必要なWebアプリケーションやモバイルアプリ
トークン自体に権限やユーザー情報を含める必要がある場合
短期間の有効期限でセキュリティを高めたい場合
ステートレスな認証が望ましい場合
多くの場合、両方を組み合わせることもあります。例えば、APIキーでクライアントアプリケーションを識別し、JWTでエンドユーザーを認証するといった方法です。重要なのは、使用するメカニズムの特性と制約を理解し、ユースケースに合わせて選択することです。
Q5: GraphQLのAPIセキュリティはRESTと何が違いますか?
A: GraphQLにはRESTとは異なるセキュリティ上の考慮点があります:
GraphQL特有のセキュリティ課題:
クエリの複雑さ: 複雑なクエリによるDoS攻撃のリスク
過剰な取得: 一度のリクエストで大量のデータを取得されるリスク
バッチ処理攻撃: 複数の操作を一度のリクエストにまとめられる
GraphQLのセキュリティ対策:
クエリの複雑さ制限: クエリの深さ、ネストレベル、フィールド数に制限を設ける
クエリのコスト分析: 各クエリの実行コストを算出し、高コストクエリを制限
レート制限の工夫: リクエスト数だけでなく、クエリの複雑さも考慮した制限を設ける
パーシャルリゾルバー認可: フィールドごとにアクセス権限を設定
クエリホワイトリスト: 許可されたクエリのみを実行できるようにする
GraphQLでは、「何を取得できるか」だけでなく「どのように取得できるか」という点でもセキュリティ設計が必要です。RESTのエンドポイントごとの認可だけでなく、より細かい粒度でのアクセス制御が求められます。
まとめ:安全なAPI実装を習慣に

APIのセキュリティは「あとから付け足す」ものではなく、設計段階から組み込むべき重要な要素です。この記事で紹介した5つの基本対策を実装することで、多くの一般的な脆弱性から自分のAPIを守ることができます。
特に重要なポイントをもう一度おさらいしましょう:
認証と認可は別物: ユーザーが誰であるかを確認する(認証)だけでなく、そのユーザーが特定のリソースにアクセスする権限があるか(認可)も必ずチェックしましょう。
すべての入力を検証: ユーザーからの入力は常に疑い、サーバーサイドでの厳格なバリデーションを実装しましょう。
リソース保護: レート制限やリクエストサイズの制限を設け、DoS攻撃やリソース枯渇攻撃から保護しましょう。
適切なエラーハンドリング: 開発者にとって有用なエラー情報を、攻撃者に悪用されないように適切に管理しましょう。
通信の暗号化: すべてのAPI通信はHTTPS上で行い、適切なセキュリティヘッダーを設定しましょう。
APIセキュリティは継続的なプロセスです。新しい脆弱性や攻撃手法は常に登場するため、最新のセキュリティベストプラクティスを学び続け、定期的にAPIのセキュリティ監査を行うことをお勧めします。
最後に、セキュリティは単なる技術的な問題ではなく、チーム全体の意識と文化の問題でもあります。セキュリティについての知識と認識を共有し、開発の最初からセキュリティを考慮する「セキュリティバイデザイン」の考え方を広めていきましょう。
安全なAPI開発を通じて、ユーザーとデータを守るシステム構築に貢献してください。