building-vulnerability-aging-and-sla-tracking について
脆弱性の経過日数と修正SLAを追跡するためのセキュリティスキルです。深刻度別の期限、資産や脅威に応じた調整、計算、ダッシュボード、エスカレーション、コンプライアンス報告を扱います。
主な機能
- 01深刻度別の修正SLA
- 02資産・脅威に応じた期限調整
- 03脆弱性の経過日数とSLAの計算
- 04経過状況ダッシュボードの設計
- 05エスカレーションと例外処理
- 06コンプライアンスとKPIの報告
活用シーン
- 01脆弱性対応チームの修正期限設定
- 02インターネット公開資産や悪用中の資産の優先対応
- 03期限超過と修正推移の追跡
- 04経営層へのSLA遵守状況の報告
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mukul975/ anthropic-cybersecurity-skills --skill building-vulnerability-aging-and-sla-trackingインストール後、Claude Code で/building-vulnerability-aging-and-sla-trackingを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEassets/template.mdreferences/api-reference.mdstandards.mdworkflows.mdscripts/agent.pyprocess.py詳細
脆弱性の経過日数とSLAの追跡
概要
2024年には30,000件を超える新たな脆弱性が特定され(前年から17%増加)、組織は脆弱性が未修正のままどれだけの期間残っているか、また定められたサービスレベル契約(SLA)内に修正されているかを追跡する必要があります。脆弱性の経過日数は、発見から修正までの期間を測定し、SLAの追跡では深刻度に応じた期限を適用します。業界のベンチマークでは、標準的なSLAとして、緊急の脆弱性は14日、高の脆弱性は30日、中の脆弱性は60日、低の脆弱性は90日が示されていますが、より迅速な対応期間(実際に悪用されている緊急のCVEでは24~48時間)が一般的になりつつあります。このスキルでは、SLAポリシーの設計、経過日数ダッシュボードの構築、自動エスカレーションの実装、コンプライアンス指標の生成について説明します。
使用する場面
- 環境に脆弱性の経過日数とSLA追跡機能を導入または設定する場合
- コンプライアンス要件に沿ったセキュリティ制御を確立する場合
- この分野のセキュリティアーキテクチャを構築または改善する場合
- この実装を必要とするセキュリティ評価を実施する場合
前提条件
- 過去のスキャンデータを備えた脆弱性管理プラットフォーム
- 重要度評価を含む資産インベントリ
- 修正状況を追跡するITSM/チケット管理システム
- レポートプラットフォーム(Splunk、Elastic、Power BI、Grafana)
- SLAの期間とエスカレーション手順に関する関係者の合意
主要な概念
標準的な脆弱性SLAの枠組み
| 深刻度 | CVSS範囲 | 標準SLA | 短縮SLA | CISA KEV SLA |
|---|---|---|---|---|
| 緊急 | 9.0-10.0 | 14日 | 48時間 | BOD 22-01の期限 |
| 高 | 7.0-8.9 | 30日 | 7日 | 14日 |
| 中 | 4.0-6.9 | 60日 | 30日 | N/A |
| 低 | 0.1-3.9 | 90日 | 60日 | N/A |
| 情報 | 0.0 | 可能な範囲で対応 | 可能な範囲で対応 | N/A |
SLAの適応的な調整要素
| 要素 | 調整 | 根拠 |
|---|---|---|
| インターネットに公開された資産 | SLAを50%短縮 | 露出リスクが高い |
| CISA KEVに掲載 | 48時間に変更 | 悪用が確認済み |
| EPSS > 0.7 | SLAを50%短縮 | 悪用される可能性が高い |
| Tier 1(最重要)資産 | SLAを25%短縮 | ビジネスへの影響が最大 |
| 代替の制御策を実施済み | SLAを25%延長 | リスクを部分的に緩和 |
| ベンダーのパッチが未提供 | レビュー日を設定して例外扱い | 現時点では修正できない |
主要業績評価指標(KPI)
| KPI | 計算式 | 目標 |
|---|---|---|
| 平均修正時間(MTTR) | Avg(remediation_date - discovery_date) | 全体で30日未満 |
| SLA遵守率 | (SLA内に修正された脆弱性数 / 脆弱性の総数) * 100 | 90%以上 |
| 期限超過の脆弱性数 | 経過日数 > SLAとなる件数 | 減少傾向 |
| 脆弱性の経過日数分布 | 経過日数の区分ごとの件数(0-14d、15-30d、31-60d、60+d) | 大半が0~30日 |
| 修正速度 | 週ごとのクローズ件数 | 増加傾向 |
| 例外率 | (例外数 / 脆弱性の総数) * 100 | 5%未満 |
ワークフロー
ステップ1:SLAポリシー文書を定義する
Vulnerability Remediation SLA Policy v1.0
1. Scope: All information systems and applications
2. Severity Classification: Based on CVSS v4.0/v3.1 base score
3. SLA Timelines: See Standard SLA Framework table
4. Adaptive Modifiers: Applied based on asset context
5. Exception Process:
- Must be documented with business justification
- Requires compensating control description
- Maximum extension: 90 days (one renewal)
- CISO approval required for Critical/High exceptions
6. Escalation Path:
- 50% SLA elapsed: Automated reminder to asset owner
- 75% SLA elapsed: Escalation to manager
- 100% SLA elapsed (overdue): CISO notification
- 120% SLA elapsed: VP/CTO escalation
7. Metrics Reporting: Monthly to security committee
ステップ2:経過日数の計算エンジンを構築する
import pandas as pd
from datetime import datetime, timedelta
class VulnerabilityAgingTracker:
"""Track vulnerability aging and SLA compliance."""
SLA_DAYS = {
"Critical": 14,
"High": 30,
"Medium": 60,
"Low": 90,
}
def __init__(self, sla_overrides=None):
if sla_overrides:
self.SLA_DAYS.update(sla_overrides)
def calculate_aging(self, vulns_df):
"""Calculate aging metrics for each vulnerability."""
today = datetime.now()
vulns_df["discovery_date"] = pd.to_datetime(vulns_df["discovery_date"])
vulns_df["remediation_date"] = pd.to_datetime(
vulns_df["remediation_date"], errors="coerce"
)
vulns_df["age_days"] = vulns_df.apply(
lambda row: (row["remediation_date"] - row["discovery_date"]).days
if pd.notna(row["remediation_date"])
else (today - row["discovery_date"]).days,
axis=1
)
vulns_df["sla_days"] = vulns_df["severity"].map(self.SLA_DAYS)
vulns_df["sla_deadline"] = vulns_df["discovery_date"] + \
pd.to_timedelta(vulns_df["sla_days"], unit="D")
vulns_df["is_overdue"] = vulns_df.apply(
lambda row: row["age_days"] > row["sla_days"]
if pd.isna(row["remediation_date"]) else False,
axis=1
)
vulns_df["sla_compliance"] = vulns_df.apply(
lambda row: row["age_days"] <= row["sla_days"]
if pd.notna(row["remediation_date"]) else None,
axis=1
)
vulns_df["days_overdue"] = vulns_df.apply(
lambda row: max(0, row["age_days"] - row["sla_days"])
if row["is_overdue"] else 0,
axis=1
)
vulns_df["sla_pct_elapsed"] = (
vulns_df["age_days"] / vulns_df["sla_days"] * 100
).round(1)
return vulns_df
def generate_kpis(self, vulns_df):
"""Generate KPI summary from aging data."""
open_vulns = vulns_df[vulns_df["remediation_date"].isna()]
closed_vulns = vulns_df[vulns_df["remediation_date"].notna()]
kpis = {
"total_vulnerabilities": len(vulns_df),
"open_vulnerabilities": len(open_vulns),
"closed_vulnerabilities": len(closed_vulns),
"overdue_count": open_vulns["is_overdue"].sum(),
"mttr_days": closed_vulns["age_days"].mean() if len(closed_vulns) > 0 else 0,
"sla_compliance_rate": (
closed_vulns["sla_compliance"].mean() * 100
if len(closed_vulns) > 0 else 0
),
}
kpis["overdue_by_severity"] = (
open_vulns[open_vulns["is_overdue"]]
.groupby("severity")
.size()
.to_dict()
)
return kpis
def get_escalation_list(self, vulns_df):
"""Get vulnerabilities requiring escalation."""
open_vulns = vulns_df[vulns_df["remediation_date"].isna()].copy()
escalations = []
for _, vuln in open_vulns.iterrows():
pct = vuln["sla_pct_elapsed"]
if pct >= 120:
level = "VP/CTO Escalation"
elif pct >= 100:
level = "CISO Notification"
elif pct >= 75:
level = "Manager Escalation"
elif pct >= 50:
level = "Owner Reminder"
else:
continue
escalations.append({
"cve_id": vuln.get("cve_id", ""),
"severity": vuln["severity"],
"age_days": vuln["age_days"],
"sla_days": vuln["sla_days"],
"days_overdue": vuln["days_overdue"],
"sla_pct": pct,
"escalation_level": level,
"asset": vuln.get("asset", ""),
"owner": vuln.get("owner", ""),
})
return pd.DataFrame(escalations)
ステップ3:ダッシュボードで可視化する
# Grafana/Kibana query examples for vulnerability aging
# Age distribution histogram (Elasticsearch)
age_distribution_query = {
"aggs": {
"age_buckets": {
"range": {
"field": "age_days",
"ranges": [
{"key": "0-7 days", "to": 8},
{"key": "8-14 days", "from": 8, "to": 15},
{"key": "15-30 days", "from": 15, "to": 31},
{"key": "31-60 days", "from": 31, "to": 61},
{"key": "61-90 days", "from": 61, "to": 91},
{"key": "90+ days", "from": 91},
]
}
}
}
}
# SLA compliance trend (monthly)
sla_trend_query = {
"aggs": {
"monthly": {
"date_histogram": {"field": "remediation_date", "interval": "month"},
"aggs": {
"within_sla": {
"filter": {"script": {
"source": "doc['age_days'].value <= doc['sla_days'].value"
}}
}
}
}
}
}
ベストプラクティス
- 達成可能なSLA目標から始め、プロセスの成熟に応じて期間を短縮します
- CVSSスコアだけでなく、資産の重要度と脅威の状況に応じてSLAを調整します
- エスカレーション通知を自動化し、手作業による追跡の負担を軽減します
- 改善を示すため、MTTRの推移を月ごとに追跡します
- 文書化された代替の制御策を必須とする例外ワークフローを構築します
- 説明責任を果たすため、SLA遵守状況を毎月経営幹部に報告します
- セキュリティ委員会や取締役会向けの報告に経過日数の指標を含めます
- エンドツーエンドで修正状況を可視化できるよう、SLA追跡をITSMチケット管理と統合します
よくある落とし穴
- チームが達成できない非現実的な SLA 目標を設定し、SLA 疲れを引き起こすこと
- 資産の重要度に応じて SLA を調整せず、すべてのシステムを同等に扱うこと
- 例外プロセスがなく、チームが SLA を無視するか、一律の免除を申請せざるを得ないこと
- 脆弱性の経過期間や SLA の遵守状況を考慮せず、未解決の脆弱性数だけを測定すること
- 発見日ではなく報告日を使い、発見日から SLA の計測を開始しないこと
- チームの成熟度が向上しても、SLA を再設定しないこと
関連スキル
- implementing-vulnerability-remediation-sla
- building-executive-vulnerability-risk-report
- implementing-security-metrics-and-kpis
- performing-remediation-validation-scanning
コメント
Markdown 対応