Webアプリケーション・API開発で押さえるべき主要な脆弱性と、その対策をまとめたリファレンスです。 分類は OWASP Top 10:2025 をベースにし、個別の代表的な脆弱性と横断的なベストプラクティスを補足しています。
目次
- OWASP Top 10:2025 概要
- カテゴリ別の詳細と対策
- 代表的な個別脆弱性一覧
- 横断的なセキュリティ対策ベストプラクティス
- 推奨HTTPセキュリティヘッダー
- 開発ライフサイクル別チェックリスト
- 参考資料
1. OWASP Top 10:2025 概要
| 順位 | カテゴリ | 概要 | 2021年版からの主な変化 |
|---|---|---|---|
| A01 | アクセス制御の不備(Broken Access Control) | 権限のないデータ・機能へのアクセス | 引き続き1位。SSRFを統合 |
| A02 | セキュリティ設定ミス(Security Misconfiguration) | 不適切なデフォルト設定・不要機能の有効化 | 5位 → 2位 |
| A03 | ソフトウェアサプライチェーンの不備(Software Supply Chain Failures) | 依存ライブラリ・ビルド基盤・配布経路の侵害 | 新設(旧「脆弱で古いコンポーネント」を拡張) |
| A04 | 暗号化の失敗(Cryptographic Failures) | 機密データの不十分な暗号化 | 2位 → 4位 |
| A05 | インジェクション(Injection) | SQL / OSコマンド / XSS など | 3位 → 5位 |
| A06 | 安全でない設計(Insecure Design) | 設計段階の脅威考慮不足 | 4位 → 6位 |
| A07 | 認証の失敗(Authentication Failures) | 認証・セッション管理の不備 | 名称を簡潔化 |
| A08 | ソフトウェア/データの完全性の不備(Software or Data Integrity Failures) | 署名なし更新・安全でないデシリアライズ | 順位維持 |
| A09 | セキュリティログとアラートの不備(Security Logging and Alerting Failures) | 検知・通知・対応ができない | 「監視」→「アラート」に重点 |
| A10 | 例外状況の不適切な処理(Mishandling of Exceptional Conditions) | エラー処理の不備、フェイルオープン | 新設 |
2. カテゴリ別の詳細と対策
A01: アクセス制御の不備
典型例
- URLやIDの書き換えで他人のデータを閲覧できる(IDOR)
- 一般ユーザーが管理者APIを呼べる
- CORSの過剰な許可
- SSRF:サーバーに内部ネットワークやクラウドのメタデータ(
169.254.169.254)へリクエストさせる
対策
- デフォルト拒否(deny by default)。公開リソース以外はすべて認可必須にする
- 認可チェックはサーバー側で、全エンドポイント共通の仕組み(ミドルウェア等)で実施する
- リソース取得時は「所有者 = ログインユーザー」を必ずクエリ条件に含める
- 推測しにくいID(UUID等)を使う。ただし認可チェックの代わりにはしない
- SSRF対策:外部URL取得は許可リスト方式、内部IPアドレスへの解決をブロック、IMDSv2を強制
- アクセス制御の失敗をログに記録してアラートを出す
A02: セキュリティ設定ミス
典型例
- デフォルトパスワード・サンプルアプリの放置
- 本番環境でのデバッグモード、詳細なスタックトレースの表示
- S3バケット等ストレージの公開設定ミス
- 不要なポート・サービス・HTTPメソッドの有効化
対策
- IaC(Terraform等)で設定をコード化し、レビューとドリフト検知を行う
- 環境ごとの設定差分を最小化し、ハードニング手順を自動化する
- 不要な機能・ポート・アカウント・ドキュメントを削除する
- CSPM / IaCスキャナー(Checkov、tfsec等)で設定ミスを継続的に検査する
- セキュリティヘッダーを設定する(5章)
A03: ソフトウェアサプライチェーンの不備
典型例
- 既知の脆弱性を持つライブラリの使用
- タイポスクワッティング・依存関係かく乱(dependency confusion)
- 侵害されたメンテナーアカウントからの悪性バージョン公開
- CI/CDパイプラインやビルドサーバーの侵害
対策
- SBOM(CycloneDX / SPDX)を生成し、依存関係を可視化する
- SCAツール(Dependabot、Renovate、Snyk、Trivy等)で継続的にスキャンする
- ロックファイルをコミットし、バージョンを固定する
- プライベートレジストリのスコープ設定で依存関係かく乱を防ぐ
- 成果物に署名(Sigstore / cosign)し、SLSAフレームワークに沿ってビルドの来歴を管理する
- CI/CDの権限を最小化し、シークレットは短命トークン(OIDC連携)にする
- 公開直後のパッケージバージョンは一定期間導入を待つ運用も有効
A04: 暗号化の失敗
典型例
- 平文通信(HTTP)、古いTLSバージョン
- MD5 / SHA-1でのパスワード保存、ソルトなしハッシュ
- ハードコードされた暗号鍵
- 弱い乱数生成器の使用
対策
- 通信は TLS 1.2以上(推奨 TLS 1.3)、HSTSを有効化する
- パスワードは Argon2id(または bcrypt / scrypt)でハッシュ化する
- 保存データは AES-256-GCM 等の認証付き暗号で暗号化する
- 鍵はKMS / HSMで管理し、ローテーションする
- 乱数は暗号論的に安全な生成器(
crypto.randomBytes、secrets等)を使う - 不要な機密データは保持しない(データ最小化)
- 量子耐性暗号(PQC)への移行計画を検討しておく
A05: インジェクション
典型例
- SQLインジェクション
- OSコマンドインジェクション
- クロスサイトスクリプティング(XSS)
- LDAP / NoSQL / テンプレートインジェクション
- LLMアプリにおけるプロンプトインジェクション
対策
- プレースホルダ(パラメータ化クエリ)やORMを使用し、文字列連結でクエリを組み立てない
- シェルを経由しないAPIで外部コマンドを実行し、引数は配列で渡す
- 出力時に文脈に応じたエスケープを行う(HTML / JS / URL / CSS)
- フレームワークの自動エスケープを無効化しない(
dangerouslySetInnerHTML、v-html等に注意) - 入力は許可リスト方式で検証する
- CSPでXSSの影響を緩和する
- LLM連携では、外部入力を指示として扱わない設計にし、ツール実行権限を最小化する
A06: 安全でない設計
典型例
- レート制限のないパスワードリセット・OTP検証
- ビジネスロジックの悪用(クーポンの多重適用、在庫の買い占め等)
- 信頼境界が不明確なアーキテクチャ
対策
- 設計段階で脅威モデリング(STRIDE等)を実施する
- 悪用ケース(abuse case)をユーザーストーリーと並べて定義する
- セキュアデザインパターン・リファレンスアーキテクチャを再利用する
- レート制限・リソースの上限値を設計に組み込む
- 階層ごとに信頼境界を定め、テナント分離を徹底する
A07: 認証の失敗
典型例
- ブルートフォース・クレデンシャルスタッフィングへの無防備
- 弱いパスワードの許可
- セッションIDの固定・推測・ログアウト後の再利用
- 多要素認証(MFA)の未導入
対策
- MFAを導入する。可能であればパスキー(FIDO2 / WebAuthn)を採用する
- 漏えい済みパスワードリストとの照合を行う(NIST SP 800-63B準拠)
- ログイン試行にレート制限・段階的遅延を設ける
- ログイン成功時にセッションIDを再生成し、適切な有効期限を設定する
- Cookieに
Secure/HttpOnly/SameSite属性を付与する - ログイン失敗時のメッセージを統一し、ユーザー列挙を防ぐ
- 自前実装より実績ある認証基盤(IdP、OIDC)を優先する
A08: ソフトウェア/データの完全性の不備
典型例
- 信頼できないデータのデシリアライズ(Java、PHP、Pythonのpickle等)
- 署名検証のない自動アップデート
- 改ざん可能なCDNからのスクリプト読み込み
対策
- 信頼できないデータのデシリアライズを避け、JSON等の単純なフォーマットを使う
- 外部スクリプトにSRI(Subresource Integrity)を付与する
- アップデート・成果物のデジタル署名を検証する
- JWTは署名アルゴリズムを固定し、
alg: noneを拒否する
A09: セキュリティログとアラートの不備
典型例
- ログイン失敗・権限エラーを記録していない
- ログはあるが誰も見ておらず、アラートもない
- ログにパスワードや個人情報が出力されている
対策
- 認証・認可・入力検証の失敗、重要操作をログに記録する
- ログはSIEM等に集約し、改ざんできない形で保管する
- 異常検知ルールとアラートを設定し、対応手順(Runbook)を整備する
- 機密情報はログにマスキングして出力する
- ログインジェクション対策として改行等をエスケープする
- インシデント対応訓練を定期的に実施する
A10: 例外状況の不適切な処理
典型例
- 例外発生時に認可チェックがスキップされる(フェイルオープン)
- エラーメッセージで内部情報(SQL文、パス、バージョン)が漏えいする
- トランザクション途中の失敗で不整合な状態が残る
- 未処理例外によるサービス停止(DoS)
対策
- フェイルセーフ(fail closed):エラー時はアクセスを拒否する側に倒す
- ユーザー向けには汎用メッセージを返し、詳細はサーバーログにのみ記録する
- グローバル例外ハンドラーを設け、未処理例外を確実に捕捉する
- トランザクションを使い、失敗時は確実にロールバックする
- タイムアウト・リトライ上限・サーキットブレーカーを設定する
- 異常系のテスト(ファジング、カオスエンジニアリング)を行う
3. 代表的な個別脆弱性一覧
| 脆弱性 | 概要 | 主な対策 | 関連カテゴリ |
|---|---|---|---|
| SQLインジェクション | 入力値によりSQL文を改変される | プレースホルダ、ORM、最小権限DBユーザー | A05 |
| XSS(反射型/格納型/DOM型) | 悪意あるスクリプトを被害者のブラウザで実行される | 出力エスケープ、CSP、HttpOnly Cookie | A05 |
| CSRF | ログイン中のユーザーに意図しない操作をさせる | CSRFトークン、SameSite Cookie、Origin検証 | A01 |
| SSRF | サーバーから内部リソースへリクエストさせる | 許可リスト、内部IPブロック、IMDSv2 | A01 |
| IDOR | IDの変更で他人のリソースにアクセスできる | オブジェクト単位の認可チェック | A01 |
| パストラバーサル | ../ で想定外のファイルにアクセスされる | パスの正規化と基準ディレクトリの検証、ID参照 | A01 |
| OSコマンドインジェクション | シェルに任意のコマンドを実行される | シェル非経由のAPI、引数の配列渡し | A05 |
| XXE | XML外部実体参照によるファイル読み取り・SSRF | 外部実体・DTDの無効化 | A02 |
| 安全でないデシリアライズ | オブジェクト復元時に任意コードを実行される | 信頼できないデータを復元しない、型の制限 | A08 |
| オープンリダイレクト | 正規ドメイン経由でフィッシングサイトへ誘導される | リダイレクト先の許可リスト | A01 |
| クリックジャッキング | 透明なiframeで意図しないクリックをさせる | frame-ancestors、X-Frame-Options | A02 |
| セッション固定 | 攻撃者が用意したセッションIDを使わせる | ログイン時のセッションID再生成 | A07 |
| ブルートフォース/クレデンシャルスタッフィング | パスワードの総当たり・使い回しを悪用される | レート制限、MFA、漏えいパスワード照合 | A07 |
| JWTの不備 | alg: none、弱い秘密鍵、検証漏れ | アルゴリズム固定、強い鍵、exp/aud の検証 | A07 / A08 |
| マスアサインメント | 想定外のプロパティ(isAdmin 等)を更新される | 更新可能フィールドの許可リスト(DTO) | A01 |
| レースコンディション | 同時リクエストで残高・在庫チェックを回避される | 排他制御、楽観ロック、冪等キー | A06 |
| ReDoS | 正規表現のバックトラッキングでCPUを枯渇させる | 安全な正規表現エンジン、入力長制限 | A06 |
| ファイルアップロードの不備 | Webシェル等の悪性ファイルを配置・実行される | 拡張子とMIMEの検証、別ドメイン配信、実行権限なし | A05 / A02 |
| 機密情報のハードコード | ソースコードにAPIキーやパスワードが含まれる | シークレット管理基盤、git-secrets / gitleaks | A04 |
| プロンプトインジェクション | LLMへの入力で指示を上書きされる | 入力と指示の分離、出力検証、ツール権限の最小化 | A05 / A06 |
4. 横断的なセキュリティ対策ベストプラクティス
4.1 基本原則
| 原則 | 内容 |
|---|---|
| 最小権限 | ユーザー・サービス・CIには必要最小限の権限だけを与える |
| 多層防御 | 単一の対策に依存せず、複数の防御層を重ねる |
| デフォルト拒否 | 明示的に許可したもの以外は拒否する |
| フェイルセーフ | 障害時は安全側(拒否側)に倒す |
| ゼロトラスト | ネットワーク内部であっても無条件に信頼せず、毎回検証する |
| 攻撃対象領域の最小化 | 不要な機能・エンドポイント・依存関係を削減する |
| セキュア・バイ・デフォルト | 初期状態で安全な設定にする |
4.2 入力・出力
- すべての外部入力(ヘッダー、Cookie、ファイル、外部APIのレスポンスを含む)を信頼しない
- 検証はサーバー側で実施する(クライアント側の検証はUXのためと割り切る)
- スキーマ検証(JSON Schema、Zod、Pydantic等)で型・長さ・範囲を制限する
- 出力時は文脈に応じたエンコーディングを行う
4.3 認証・認可
- 認証は実績ある基盤(OIDC / SAML / パスキー)を採用する
- 認可モデル(RBAC / ABAC / ReBAC)を明確化し、一元的に実装する
- APIトークンには有効期限とスコープを設定する
- 管理者機能はネットワークレベルでも分離する
4.4 シークレット管理
- シークレットはVault、AWS Secrets Manager、GCP Secret Manager等で管理する
.envファイルをリポジトリにコミットしない(.gitignoreと pre-commit フックで防止)- 長期の静的クレデンシャルより、短命トークン・ワークロードIDを使う
- 漏えい時に備えてローテーション手順を整備する
4.5 インフラ・クラウド
- ネットワークをセグメント化し、DBなどは非公開サブネットに置く
- WAF・DDoS対策を導入する
- コンテナは非rootで実行し、読み取り専用ファイルシステムと最小ベースイメージを使う
- OS・ミドルウェアのパッチ適用を自動化する
- バックアップを取得し、復元テストを定期的に行う(ランサムウェア対策としてイミュータブルバックアップを含める)
4.6 API セキュリティ
- 認証・認可を全エンドポイントで必須にする
- レート制限・ページネーションの上限を設定する
- レスポンスに不要なフィールドを含めない(過剰なデータ露出を防ぐ)
- APIインベントリを管理し、古いバージョンや非公開APIを放置しない
- GraphQLでは深さ制限・複雑度制限を設け、本番ではイントロスペクションを無効化する
4.7 組織・運用
- 開発者向けのセキュアコーディング教育を定期的に実施する
- 脆弱性開示ポリシー(
security.txt)とバグバウンティを検討する - インシデント対応計画を策定し、訓練する
- 脆弱性はCVSS / EPSS / KEVを参考に優先度付けし、SLAを定めて修正する
5. 推奨HTTPセキュリティヘッダー
| ヘッダー | 推奨値の例 | 目的 |
|---|---|---|
Strict-Transport-Security | max-age=63072000; includeSubDomains; preload | HTTPSの強制 |
Content-Security-Policy | default-src 'self'; script-src 'self' 'nonce-xxx'; object-src 'none'; frame-ancestors 'none'; base-uri 'self' | XSS・クリックジャッキングの緩和 |
X-Content-Type-Options | nosniff | MIMEスニッフィングの防止 |
X-Frame-Options | DENY | クリックジャッキング防止(旧ブラウザ向け) |
Referrer-Policy | strict-origin-when-cross-origin | リファラーによる情報漏えいの抑制 |
Permissions-Policy | camera=(), microphone=(), geolocation=() | ブラウザ機能の制限 |
Cross-Origin-Opener-Policy | same-origin | クロスオリジンのウィンドウ分離 |
Cross-Origin-Resource-Policy | same-origin | リソースの不正な読み込み防止 |
Cache-Control | no-store(機密情報を含むページ) | 機密情報のキャッシュ防止 |
Cookie 属性
Set-Cookie: __Host-session=xxxx; Path=/; Secure; HttpOnly; SameSite=Lax
__Host-プレフィックスで、ドメイン指定なし・Secure必須を強制するHttpOnlyでJavaScriptからのアクセスを防ぐSameSite=LaxまたはStrictでCSRFを緩和する
6. 開発ライフサイクル別チェックリスト
要件定義・設計
- セキュリティ要件を定義した(OWASP ASVSのレベルを選定)
- 脅威モデリングを実施した
- 扱うデータを分類し、保護レベルを決めた
- 認証・認可方式を設計した
- 悪用ケースを洗い出した
実装
- パラメータ化クエリを使用している
- 出力エスケープを適切に行っている
- シークレットをハードコードしていない
- エラー時に内部情報を返していない
- 依存ライブラリのバージョンを固定している
- コードレビューでセキュリティ観点を確認している
テスト
- SAST(静的解析:Semgrep、CodeQL等)を実施した
- SCA(依存関係スキャン)を実施した
- DAST(動的解析:OWASP ZAP、Burp Suite等)を実施した
- シークレットスキャン(gitleaks、TruffleHog等)を実施した
- 重要システムではペネトレーションテストを実施した
- 認可のテスト(他ユーザーのリソースへのアクセス)を自動化した
デプロイ
- 本番環境でデバッグモードを無効化した
- セキュリティヘッダーを設定した
- TLS設定を検証した
- IaCスキャンを通過した
- コンテナイメージをスキャンした
- 成果物に署名した
運用
- ログを集約し、アラートを設定した
- 脆弱性情報(CVE、JVN)を継続的に監視している
- パッチ適用のSLAを定めて運用している
- バックアップと復元テストを実施している
- インシデント対応手順を整備し、訓練している
- アクセス権限を定期的に棚卸ししている
7. 参考資料
- OWASP Top 10:2025
- OWASP API Security Top 10
- OWASP Top 10 for LLM Applications
- OWASP ASVS(Application Security Verification Standard)
- OWASP Cheat Sheet Series
- CWE Top 25 Most Dangerous Software Weaknesses
- IPA「安全なウェブサイトの作り方」
- NIST SP 800-63B(デジタルアイデンティティガイドライン)
- SLSA(Supply-chain Levels for Software Artifacts)
- CISA Known Exploited Vulnerabilities Catalog