# セキュリティログ設計と検知エンジニアリング実践ガイド【2026年版】Sigma・MITRE ATT&CK・SIEMで『気づける』状態を作る

> 「検知できないものは守れない」を解決する、ログ設計と検知エンジニアリングの実践ガイド。OWASPに沿った“何を記録し何を記録しないか”、型安全な構造化ログと秘密情報のマスキング、Sigmaによるベンダー中立な検知ルール、MITRE ATT&CKへのマッピング、Detection as Codeまでを実コードで解説します。

- 公開日: 2026-06-28
- 著者: 友田 陽大
- タグ: セキュリティ, ログ設計, 検知エンジニアリング, Sigma, セキュリティエンジニア
- URL: https://tomodahinata.com/blog/security-logging-detection-engineering-sigma-mitre-attack-siem-guide
- カテゴリ: セキュリティエンジニア・キャリア
- 総合ガイド: https://tomodahinata.com/blog/security-engineer-how-to-become-roadmap-skills-certification-guide

## 要点

- 「検知できないものは守れない」。攻撃は必ずしも防げないが、“気づけない”ことは致命傷になる。OWASP Top 10でも『セキュリティログとアラートの不備(A09)』は常連の弱点
- ログ設計の核心は『何を記録し、何を記録しないか』。認証成否・認可拒否・重要操作は記録する。一方でパスワード・トークン・カード番号・個人情報は絶対にログに書かない（ログが新たな漏えい源になる）
- 構造化ログ（JSON）＋相関ID＋秘密情報の自動マスキングが土台。人間が読むテキストではなく、機械が検索・相関できる形で出す。型安全なロガーで“危険な値を構造的に書けない”設計にする
- 検知ルールはSigmaで書く。Sigmaはベンダー中立なYAML形式で、Splunk・Sentinel・Elastic等へ変換できる。各ルールをMITRE ATT&CKの技術ID（例: T1110 総当たり）に紐づけ、抜けを可視化する
- 検知は“コード”として運用する（Detection as Code）。ルールをGitで版管理し、テストし、CIで配備する。アラート疲れを避けるため、誤検知の継続的なチューニングが品質を決める

---

セキュリティの世界には、残酷な事実があります。**「攻撃は、必ずしも防げない」**。ゼロデイ脆弱性、内部不正、巧妙なフィッシング——どれだけ防御を固めても、侵害の可能性をゼロにはできません。だからこそ、防御と同じくらい重要なのが——**「気づけること」**です。

侵害の調査で最も多い悲劇は、「いつ・どこから・何が起きたのか、ログが無くて分からない」というものです。実際、[OWASP Top 10](https://owasp.org/Top10/2025/)でも**「セキュリティログとアラートの不備（A09）」**は繰り返しランクインしています。本記事は、**「検知できる状態」を作る**ための、ログ設計と検知エンジニアリングを、公式情報（[OWASP Logging Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html)、[Sigma](https://github.com/SigmaHQ/sigma)、[MITRE ATT&CK](https://attack.mitre.org/)）に忠実な実コードで解説します。

> **この記事の位置づけ：** NIST CSF 2.0の**「検知（Detect）」**を担う中核技能です。職種全体は[セキュリティエンジニアになるには](/blog/security-engineer-how-to-become-roadmap-skills-certification-guide)、検知の前段の防御は[セキュアコーディング実践](/blog/secure-coding-practices-nist-ssdf-owasp-asvs-engineer-guide)、検知の後段の対応は[インシデント対応](/blog/incident-response-nist-800-61r3-csirt-runbook-playbook-production-guide)を参照してください。

---

## 0. 何を記録し、何を記録しないか

ログ設計は、「とにかく全部出す」では失敗します。**ノイズに埋もれて重要な異変が見えなくなり、かつ機密情報を撒き散らす**からです。[OWASP Logging Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html)に沿って、記録すべきものと、絶対に記録してはいけないものを分けます。

### 記録すべきセキュリティイベント

| カテゴリ | 具体例 |
|---|---|
| **認証** | ログイン成功・失敗、ログアウト、MFAの成否、パスワード変更 |
| **認可** | アクセス拒否（権限不足）、ロール変更、特権操作 |
| **重要操作** | データの作成・更新・削除、設定変更、エクスポート |
| **入力検証の失敗** | 不正な入力の拒否（攻撃の予兆） |
| **異常** | 例外、レート制限の発動、想定外の状態遷移 |

### 絶対に記録してはいけないもの

**ログそのものが新たな情報漏えい源になる**——これを忘れてはいけません。

- **パスワード・トークン・APIキー・セッションID**（平文はもちろんハッシュ前も）
- **クレジットカード番号・CVV**（PCI DSS違反）
- **個人情報（PII）**——氏名・住所・電話番号などは最小化、必要ならマスキング
- **機密性の高い業務データ**

「デバッグのために一時的に出した秘密情報」が本番ログに残り、それが漏えいする——典型的な事故です。**秘密を“うっかり書けない”構造**を、ロガー側で持つのが正解です。

---

## 1. 型安全な構造化ロガー — 秘密を構造的に書けなくする

人間が読むためのテキストログ（`"user alice logged in from 1.2.3.4"`）は、機械が検索・相関するのに向きません。現代の標準は **構造化ログ（JSON）** です。フィールドで検索でき、相関ID（リクエストID）で一連の流れを追え、SIEMにそのまま取り込めます。

さらに、**秘密情報を自動でマスキングする**ロガーにすれば、「うっかり漏らす」事故を構造的に防げます。

```ts
// security-logger.ts — 構造化セキュリティログを出し、秘密情報を自動マスキングする。
import { z } from "zod";

// ① 記録してよいイベント種別を列挙（型で縛る＝勝手な自由文字列を防ぐ）。
const SecurityEvent = z.enum([
  "auth.login.success",
  "auth.login.failure",
  "authz.access.denied",
  "data.export",
  "ratelimit.triggered",
]);
type SecurityEvent = z.infer<typeof SecurityEvent>;

// ② ログに含めてはいけないキー。値を見ずにキー名で機械的に伏せる。
const REDACT_KEYS = new Set([
  "password", "token", "secret", "authorization",
  "apikey", "api_key", "sessionid", "session_id", "cookie", "creditcard",
]);

function redact(meta: Record<string, unknown>): Record<string, unknown> {
  const safe: Record<string, unknown> = {};
  for (const [key, value] of Object.entries(meta)) {
    safe[key] = REDACT_KEYS.has(key.toLowerCase()) ? "[REDACTED]" : value;
  }
  return safe;
}

interface LogContext {
  readonly requestId: string;  // 相関ID：一連のリクエストを横断で追える
  readonly userId?: string;    // 主体（無ければ匿名）
  readonly ip?: string;
}

/** セキュリティイベントを構造化JSONで出力する。秘密は自動で伏せられる。 */
export function logSecurityEvent(
  event: SecurityEvent,
  ctx: LogContext,
  meta: Record<string, unknown> = {},
): void {
  const entry = {
    ts: new Date().toISOString(),
    level: "security",
    event,
    ...ctx,
    ...redact(meta), // ③ 秘密はここで構造的に伏せられる
  };
  // 1行1JSON（JSON Lines）。SIEM/ログ基盤がそのまま取り込める。
  console.log(JSON.stringify(entry));
}
```

```ts
// 使用例：ログイン失敗を記録する。password を渡しても自動で伏せられる。
logSecurityEvent("auth.login.failure", { requestId, ip }, {
  email: "alice@example.com",
  password: "hunter2",       // → "[REDACTED]" として出力される（漏れない）
  reason: "invalid_credentials",
});
// 出力: {"ts":"2026-06-28T...","level":"security","event":"auth.login.failure",
//        "requestId":"...","ip":"...","email":"alice@example.com",
//        "password":"[REDACTED]","reason":"invalid_credentials"}
```

設計の要点は3つです。**(1) イベント種別を型で列挙**して野放図な文字列を防ぐ、**(2) 相関ID**で横断追跡を可能にする、**(3) キー名ベースのマスキング**で秘密を構造的に伏せる。これで「検索でき、相関でき、漏らさない」ログの土台ができます。

---

## 2. 検知エンジニアリング — Sigma で「異常」を定義する

ログを貯めるだけでは、誰も見ません。**「この条件が起きたらアラートを出す」**という検知ルールが要ります。ここで業界標準になりつつあるのが、**[Sigma](https://github.com/SigmaHQ/sigma)** です。

Sigmaは、**ベンダー中立なYAML形式の検知ルール**です。一度書けば、Splunk・Microsoft Sentinel・Elastic・QRadar など各SIEMのクエリに**変換**できます。「SIEMごとにクエリ言語を覚え直す」地獄から解放されるのが最大の利点です。

下は、**短時間に連続したログイン失敗（総当たり攻撃の予兆）**を検知するSigmaルールです。**MITRE ATT&CKの技術ID（T1110: Brute Force）に紐づける**ことで、「自分たちはATT&CKのどの攻撃技術をカバーできているか」が可視化されます。

```yaml
# rules/brute_force_login.yml — 総当たりログインの検知（Sigma形式）
title: 短時間における連続ログイン失敗（総当たりの疑い）
id: 8f2e1a3c-0b4d-4e5f-9a1b-2c3d4e5f6a7b
status: stable
description: 同一IPからの連続したログイン失敗を検知し、総当たり攻撃を早期に捉える
references:
  - https://attack.mitre.org/techniques/T1110/
author: friend yota
date: 2026/06/28
logsource:
  product: application
  service: auth
detection:
  selection:
    event: "auth.login.failure"   # 構造化ログの event フィールドに一致
  timeframe: 5m                    # 5分の時間枠で…
  condition: selection | count() by ip > 10   # 同一IPから10回超の失敗
fields:
  - ip
  - email
falsepositives:
  - 正規ユーザーのパスワード失念（ロックアウト方針と併せて評価する）
level: high
tags:
  - attack.credential_access
  - attack.t1110          # MITRE ATT&CK: Brute Force
```

ルールの構造はシンプルです——**`logsource`（どのログか）＋ `detection`（何に一致するか）＋ `condition`（アラート条件）＋ メタ데이터（`tags` で ATT&CK 技術ID）**。`falsepositives`（誤検知の可能性）を明記する文化が、後述のアラート疲れ対策に効きます。

---

## 3. MITRE ATT&CK で「カバレッジ」を測る

個々のルールを書くだけでは、「自分たちは何を検知できて、何を見落としているか」が分かりません。そこで使うのが **[MITRE ATT&CK](https://attack.mitre.org/)** です。ATT&CKは、実際の攻撃者の戦術（Tactics）と技術（Techniques）を体系化した、世界共通の“攻撃の地図”です。

各Sigmaルールを `attack.tXXXX` でATT&CK技術にマッピングしておくと、**[ATT&CK Navigator](https://mitre-attack.github.io/attack-navigator/)** 上で「カバーできている技術」を塗り分けられます。これにより、検知の議論が「なんとなく不安」から——

- **「初期アクセス（Initial Access）の検知は手薄だ」**
- **「権限昇格（Privilege Escalation）はカバーできている」**

——という**具体的なカバレッジの議論**に変わります。脅威モデリング（[STRIDE](/blog/threat-modeling-stride-data-flow-diagram-secure-design-practical-guide)）で“守るべき脅威”を洗い出し、ATT&CKで“検知のカバレッジ”を測る——攻めの地図と守りの地図が噛み合います。

---

## 4. Detection as Code — 検知を“コード”として運用する

検知ルールも、アプリのコードと同じ規律で運用します（**Detection as Code**）。

- **Gitで版管理する。** 誰が・いつ・なぜそのルールを足したかが追える。
- **テストする。** 既知の攻撃ログ（サンプル）でルールが発火し、正常ログで発火しないことを検証する。
- **CIで配備する。** マージされたら自動でSIEMにルールを反映する。
- **チューニングし続ける。** 誤検知（false positive）を継続的に削る。

最後の「チューニング」が、検知の品質を決定づけます。**アラート疲れ（alert fatigue）**——誤検知が多すぎて、本物のアラートまで無視されるようになる状態——は、検知体制の最大の敵です。だから各ルールに `falsepositives` を明記し、発火率を観測し、**「狼少年にならないルール」だけを残す**運用が要ります。「ルールの数」ではなく「信頼できるアラートの質」を指標にしてください。

検知が発火したあと、誰が・どう動くのか——その先は[インシデント対応](/blog/incident-response-nist-800-61r3-csirt-runbook-playbook-production-guide)の領域です。検知と対応はセットで設計して初めて意味を持ちます。

---

## 5. ログの完全性 — 改ざんされたら証拠にならない

最後に見落とされがちな点を。**ログ自体が改ざんできては、否認防止（STRIDEのRepudiation対策）になりません。** 攻撃者が侵入後に証拠隠滅でログを消す、というのは典型的な手口です。

- **追記専用（append-only）**にする。アプリの実行権限ではログを書き換え・削除できないようにする。
- **集約する。** ログを生成元のサーバーから切り離し、別の集約基盤（SIEM／ログ専用ストレージ）へ即座に転送する。侵害されたサーバー上のログだけに頼らない。
- **保持期間を定める。** 法令・契約・調査の必要性に応じて、改ざん不能な形で一定期間保持する。

「ログを取っている」と「ログが証拠になる」の間には、この**完全性**の差があります。

---

## 6. よくある質問（FAQ）

**Q. 小規模なアプリでも、ここまで必要ですか？**
A. 規模に応じて“軽く”始めれば十分です。まずは構造化ログ＋秘密のマスキング（§1）から。SIEMが無くても、認証成否・認可拒否・重要操作をJSONで出しておくだけで、いざという時の調査力が段違いになります。

**Q. 既存のロガー（pino/winston等）でもできますか？**
A. できます。本記事のロガーは原理を示すための最小実装です。pinoなどには `redact` 機能が標準であり、それを使えば本番品質の構造化ログ＋マスキングが手早く実現できます。

**Q. SIEMは高価では？無料で始められますか？**
A. クラウドのマネージドSIEMは従量課金で小さく始められます。OSSなら Elastic Stack や OpenSearch、Wazuh などがあります。まずはログを「構造化してどこかに集約する」ことが先で、SIEMの選定は後からでも間に合います。

**Q. Sigmaルールはどこから手に入る？**
A. [SigmaHQ公式リポジトリ](https://github.com/SigmaHQ/sigma)に数千の公開ルールがあります。まずはそこから自分の環境に合うものを取り込み、`sigma-cli` で各SIEMのクエリに変換するのが早道です。

**Q. ログにどこまでPIIを含めてよい？**
A. 原則は最小化です。調査に不可欠なら、識別子（ユーザーID）に留め、氏名・住所などはマスキングか参照に。個人情報保護法やGDPR等の観点でも、ログのPIIは“持たない”のが最も安全です。

---

## 7. まとめ

「守る」ことと同じくらい、「気づける」ことが重要です。検知は、防御をすり抜けた攻撃に対する**最後の、そして決定的な防衛線**です。

- **何を記録し、何を記録しないかを決める。** 認証・認可・重要操作は記録、秘密とPIIは絶対に書かない。
- **構造化ログ＋相関ID＋自動マスキング。** 検索でき、相関でき、漏らさない土台を、型安全なロガーで作る。
- **Sigmaで検知を書く。** ベンダー中立なYAMLで、各SIEMへ変換。MITRE ATT&CKで技術IDに紐づける。
- **ATT&CKでカバレッジを測る。** 「なんとなく不安」を「どの戦術が手薄か」に変える。
- **Detection as Codeで運用する。** Git・テスト・CI・継続チューニング。アラート疲れを避け、質を指標にする。
- **ログの完全性を守る。** 追記専用・別基盤への集約・適切な保持。

「検知できないものは守れない」——この一文を、設計の最初に置いてください。あなたのプロダクトのログ設計や検知体制を一度見直したい、SIEM導入や検知ルールの整備を伴走してほしい場合は、お気軽にご相談ください。

---

### 参考（公式一次情報）

- ログ設計：[OWASP Logging Cheat Sheet](https://cheatsheetseries.owasp.org/cheatsheets/Logging_Cheat_Sheet.html)／[OWASP Top 10:2025 A09](https://owasp.org/Top10/2025/)
- 検知：[Sigma（SigmaHQ）](https://github.com/SigmaHQ/sigma)／[MITRE ATT&CK](https://attack.mitre.org/)／[ATT&CK Navigator](https://mitre-attack.github.io/attack-navigator/)
- 関連：[インシデント対応](/blog/incident-response-nist-800-61r3-csirt-runbook-playbook-production-guide)／[脅威モデリング](/blog/threat-modeling-stride-data-flow-diagram-secure-design-practical-guide)
