A09 セキュリティログとアラートの不備
攻撃を止められなかったときに、気づけず、追えない状態。記録、集約、検知、警告、対応の流れのどこか1か所が途切れれば成立する。
要点
- ログイン、アクセス制御、入力の検証の失敗と、高額の取引は、利用者を特定できる形で必ず記録する。
- ログは構造化した形式で書き、値は項目として渡す。文字列の連結は、改行で偽の行を足すログインジェクションを許す。
- パスワード、トークン、セッションID、接続文字列をログに書かない。
- ログはアプリと別の権限の場所へすぐ送り、追記だけにする。手元にだけ置けば、侵入した相手が消せる。
- 警告には閾値と、受けた人がすることを書いた手順書を付ける。誰も見ない警告は無いのと同じ。
成立の条件
OWASPは、監査すべき出来事が記録されない、ログが改ざんから守られない、ログが監視されない、手元にだけ置かれる、警告の閾値と上げる先が無い、診断の走査でも警告が出ない、ログに機微な情報が出る、ログの値が符号化されない、誤検知が多すぎて重要な警告が埋もれる、手順書が無い、を挙げる[1]。
記録すべき出来事が無い
攻撃の多くは、失敗の繰り返しとして先に現れる。成功だけを記録していれば、試行の段階で気づけない。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]。
悪い例と直した例。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]。
診断で見る所
- 出来事の網羅 ログインの失敗、他人の資源へのアクセスの拒否、検証の失敗を起こし、利用者と送信元が分かる形で記録されるか。
- 警告 同じ試験で、警告が担当者に届くか。届くまでの時間。
- 符号化 改行、制御文字、HTMLを含む値を送り、ログの行が増えないか、ログの閲覧画面で解析されないか。
- 機微な情報 ログとAPMとエラー追跡の送り先に、トークン、Cookie、パスワード、個人の情報が出ていないか。
- 保全 アプリのサーバーの権限で、ログを消したり書き換えたりできないか。保存の期間。
- 手引き OWASP ASVS 5.0 の V16 が、記録と誤りの扱いの検証の要件を並べる[4]。
関連するCWE
A09に対応づけられたCWEは5個で、すべてを挙げる[1]。主な2つの定義は、MITREの各ページにある[7][10]。
| CWE | 名前 | このページの節 |
|---|---|---|
| CWE-778 | Insufficient Logging | 記録すべき出来事 |
| CWE-223 | Omission of Security-relevant Information | 記録すべき出来事 |
| CWE-221 | Information Loss or Omission | 記録すべき出来事 |
| CWE-117 | Improper Output Neutralization for Logs | ログインジェクション |
| CWE-532 | Insertion of Sensitive Information into Log File | 機微な情報 |
参照
- A09:2025 Security Logging and Alerting Failures OWASP Top 10:2025
- Logging Cheat Sheet OWASP Cheat Sheet Series
- Application Logging Vocabulary Cheat Sheet OWASP Cheat Sheet Series
- V16 Security Logging and Error Handling OWASP ASVS 5.0.0
- SP 800-92 Guide to Computer Security Log Management NIST。2006年9月
- SP 800-61 Rev. 3 Incident Response Recommendations and Considerations for Cybersecurity Risk Management NIST。2025年4月
- CWE-117 MITRE CWE
- CWE-532 MITRE CWE
- RFC 3339 Date and Time on the Internet: Timestamps IETF
- CWE-778 MITRE CWE
- A09:2021 Security Logging and Monitoring Failures OWASP Top 10:2021