A09 セキュリティログとアラートの不備

攻撃を止められなかったときに、気づけず、追えない状態。記録、集約、検知、警告、対応の流れのどこか1か所が途切れれば成立する。

OWASP Top 10:2025 A09:2025 Security Logging and Alerting Failures。対応づけられたCWEは5個[1]。2021年版の名前は Security Logging and Monitoring Failures だった[11]。2026年11月時点の記載で書いています。

要点

  • ログイン、アクセス制御、入力の検証の失敗と、高額の取引は、利用者を特定できる形で必ず記録する。
  • ログは構造化した形式で書き、値は項目として渡す。文字列の連結は、改行で偽の行を足すログインジェクションを許す。
  • パスワード、トークン、セッションID、接続文字列をログに書かない。
  • ログはアプリと別の権限の場所へすぐ送り、追記だけにする。手元にだけ置けば、侵入した相手が消せる。
  • 警告には閾値と、受けた人がすることを書いた手順書を付ける。誰も見ない警告は無いのと同じ。

成立の条件

OWASPは、監査すべき出来事が記録されない、ログが改ざんから守られない、ログが監視されない、手元にだけ置かれる、警告の閾値と上げる先が無い、診断の走査でも警告が出ない、ログに機微な情報が出る、ログの値が符号化されない、誤検知が多すぎて重要な警告が埋もれる、手順書が無い、を挙げる[1]。

記録、集約、検知、警告、対応の5段と、それぞれが途切れる典型 記録 アプリ 集約 別の権限の保管 検知 規則と閾値 警告 上げる先 対応 手順書 途切れる所 失敗を書かない 誰か分からない 改行で偽の行 手元にだけ置く 侵入者が消せる 保存の期間が短い 規則が無い 走査も素通り 規則が古い 上げる先が無い 誤検知に埋もれる 遅れて届く 手順書が無い 役割が無い 練習していない
図1 ログから対応までの5段と、それぞれが途切れる典型

記録すべき出来事が無い

攻撃の多くは、失敗の繰り返しとして先に現れる。成功だけを記録していれば、試行の段階で気づけない。OWASPは、ログインの失敗、アクセス制御の失敗、サーバーの側の入力の検証の失敗を、怪しいアカウントを特定できる利用者の情報と一緒に記録し、遅れて行う調査に足りる期間だけ保つよう求める[1][2]。

出来事語彙の例使い道
ログインの失敗authn_login_fail推測とスプレーの検知
失敗の上限に達したauthn_login_fail_maxロックと警告
アクセス制御の失敗authz_fail他人のIDを試す動きの検知
権限の変更authz_change乗っ取った後の権限の引き上げ
期限切れのセッションの使用session_use_after_expire盗んだセッションの再使用
入力の検証の失敗input_validation_failインジェクションの試行
パスワードの変更authn_password_change乗っ取りの後の締め出し

語彙は OWASP Application Logging Vocabulary による。各記録には、時刻、アプリ、出来事、重さ、利用者、送信元を、いつ、どこで、誰が、何を、の形で持たせる[2][3]。時刻は時差つきのISO 8601、RFC 3339 の形にそろえる[3][9]。

{"datetime":"2026-11-10T09:14:03+09:00","appid":"shop.order_api",
 "event":"authz_fail:u_1042,/orders/77","level":"WARN",
 "source_ip":"203.0.113.24","request_uri":"/orders/77","request_method":"GET"}

ログインジェクション

平文のログに、利用者が入れた値を連結して書くと、値の中の改行で新しい行が始まる。読む側は、偽の行を本物の記録と区別できない。ログを画面に出す管理ツールでは、値がHTMLとして解析されてXSSにもなる[2][7]。

改行を含む利用者名を連結すると、ログに成功を装う偽の行が足される 送られた利用者名 x\n09:14:05 INFO login ok user=admin \n は改行の文字そのもの 平文のログ 09:14:05 WARN login fail user=x 09:14:05 INFO login ok user=admin 2行目は利用者が書いた文字列。本物と区別できない 構造化したログ "user":"x\n09:14:05 INFO login ok…"
図2 改行を含む値が平文のログに偽の行を足す

悪い例と直した例。Node.js の架空のログイン

// 悪い例 値を連結して1行の文字列にする
logger.warn("login fail user=" + req.body.user + " ip=" + req.ip);

// 直した例 構造化したロガーに項目として渡す。改行は JSON の中で \n として符号化される
logger.warn({ event: "authn_login_fail", userid: req.body.user, source_ip: req.ip });
  • OWASPは、すべての値を無害化し、平文でなくJSONのような構造化した形式を使うよう勧める[2]。
  • ログを表示する画面は、ログの値を信頼しない入力として扱い、HTMLの文脈で符号化する。

機微な情報をログに書く

ログは、アプリのDBより広い人と仕組みに読まれ、長く保たれる。要求の本文やヘッダーを丸ごと書けば、パスワード、アクセストークン、Cookie のセッションIDがそのまま残る。OWASPは、セッションIDは必要ならハッシュにし、アクセストークン、パスワード、接続文字列、暗号の鍵を書かないよう挙げる[2]。CWE-532 に当たる[8]。

// 悪い例 要求を丸ごと書く。Authorization、Cookie、パスワードが入る
logger.info({ msg: "request", headers: req.headers, body: req.body });

// 直した例 書く項目を決める。セッションを追うにはハッシュの値を使う
logger.info({ event: "session_created", userid: user.id,
              sid_hash: sha256(sid).slice(0, 16), source_ip: req.ip });

書く項目を決めておく作りを基本にし、ロガーの伏せ字の機能は漏れを拾う二重の網として使う。IPアドレスも、他の情報と組み合わせれば個人を特定できる情報になり得る[3]。

警告と保全が無い

記録していても、手元のディスクにだけあれば、侵入した相手が消せる。集約していても、規則と閾値と上げる先が無ければ、気づくのは外部からの連絡になる。OWASPは、能動的な攻撃を即時かそれに近い速さで検知し、上げられないことを、このカテゴリの条件に挙げる[1]。

  • ログはすぐに、アプリと別の権限の保管先へ送る。読み取りの権限を絞り、改ざんと削除を検出できるようにする[2]。
  • 監査の記録は、追記だけの表のように、完全性を守る仕組みに置く[1]。
  • 警告の使い道ごとに、閾値と、受けた人がすることを書いた手順書を用意する。誤検知が多ければ規則を直す[1]。
  • 正規の処理では触れない囮のレコードやアカウントを置く。触れた時点で確度の高い警告になる[1]。
  • 診断の走査を流して、警告が出るかを確かめる。出なければ、本物の攻撃でも出ない[1]。

守り方

根本の直し方
  • 記録する出来事を、設計で決める。認証、アクセス制御、入力の検証の失敗と、価値の大きい操作、守りの仕組みの成否のすべて[1][4]。
  • ログは共通のロガーで、構造化した形式と決まった語彙で書く。値は項目として渡し、連結しない[2][3]。
  • 書いてよい項目を決め、秘密と認証の情報を書かない[2]。
  • ログを別の権限の保管先へすぐ送り、追記だけにし、期間を決めて保つ[2][5]。
  • 検知の規則、警告の上げる先、手順書を、インシデント対応の計画の一部として持つ。NIST SP 800-61 Rev. 3 は2025年4月の版[1][6]。

次は緩和の策で、根本の直し方を済ませたうえで重ねる。

  • 同じ誤りが大量に出る時は、件数と期間をまとめた記録にし、ログの溢れで重要な行が埋もれないようにする。
  • 振る舞いの分析で誤検知を減らす。規則の代わりではなく、規則に重ねる[1]。

診断で見る所

  • 出来事の網羅 ログインの失敗、他人の資源へのアクセスの拒否、検証の失敗を起こし、利用者と送信元が分かる形で記録されるか。
  • 警告 同じ試験で、警告が担当者に届くか。届くまでの時間。
  • 符号化 改行、制御文字、HTMLを含む値を送り、ログの行が増えないか、ログの閲覧画面で解析されないか。
  • 機微な情報 ログとAPMとエラー追跡の送り先に、トークン、Cookie、パスワード、個人の情報が出ていないか。
  • 保全 アプリのサーバーの権限で、ログを消したり書き換えたりできないか。保存の期間。
  • 手引き OWASP ASVS 5.0 の V16 が、記録と誤りの扱いの検証の要件を並べる[4]。

関連するCWE

A09に対応づけられたCWEは5個で、すべてを挙げる[1]。主な2つの定義は、MITREの各ページにある[7][10]。

CWE名前このページの節
CWE-778Insufficient Logging記録すべき出来事
CWE-223Omission of Security-relevant Information記録すべき出来事
CWE-221Information Loss or Omission記録すべき出来事
CWE-117Improper Output Neutralization for Logsログインジェクション
CWE-532Insertion of Sensitive Information into Log File機微な情報

参照

  1. A09:2025 Security Logging and Alerting Failures OWASP Top 10:2025
  2. Logging Cheat Sheet OWASP Cheat Sheet Series
  3. Application Logging Vocabulary Cheat Sheet OWASP Cheat Sheet Series
  4. V16 Security Logging and Error Handling OWASP ASVS 5.0.0
  5. SP 800-92 Guide to Computer Security Log Management NIST。2006年9月
  6. SP 800-61 Rev. 3 Incident Response Recommendations and Considerations for Cybersecurity Risk Management NIST。2025年4月
  7. CWE-117 MITRE CWE
  8. CWE-532 MITRE CWE
  9. RFC 3339 Date and Time on the Internet: Timestamps IETF
  10. CWE-778 MITRE CWE
  11. A09:2021 Security Logging and Monitoring Failures OWASP Top 10:2021