# Building Vulnerability Aging And Sla Tracking

> 实施漏洞老化仪表盘和 SLA 跟踪系统，根据基于严重性的时间线衡量修复绩效，并推动问责制落地。

- Skill: `killvxk/building-vulnerability-aging-and-sla-tracking` (Agent Skill, multi-file: 8 files)
- Install (CLI): `npx skillmds@latest add killvxk/building-vulnerability-aging-and-sla-tracking`
- Raw SKILL.md: https://api.skillmd.com/api/skills/killvxk/building-vulnerability-aging-and-sla-tracking/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: Apache-2.0
- Author: killvxk (https://skillmd.com/u/killvxk)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/killvxk/building-vulnerability-aging-and-sla-tracking

---

# 构建漏洞老化与 SLA 跟踪

## 概述

2024 年新发现的漏洞超过 30,000 个（比上年增加 17%），组织必须跟踪漏洞未修复的时间以及修复是否在规定的服务级别协议（SLA）内完成。漏洞老化衡量从发现到修复之间的时间，而 SLA 跟踪则强制执行基于严重性的截止时限。行业基准标准 SLA 为：关键漏洞 14 天、高危漏洞 30 天、中危漏洞 60 天、低危漏洞 90 天，但对于被主动利用的关键 CVE，更激进的时间线（24-48 小时）正越来越普遍。本技能涵盖 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 天 | 不适用 |
| 低 | 0.1-3.9 | 90 天 | 60 天 | 不适用 |
| 信息 | 0.0 | 尽力而为 | 尽力而为 | 不适用 |

### 自适应 SLA 调节系数

| 因素 | 调节系数 | 理由 |
|--------|----------|-----------|
| 互联网暴露资产 | -50% SLA | 更高的暴露风险 |
| 列入 CISA KEV | 覆盖为 48 小时 | 已确认主动利用 |
| EPSS > 0.7 | -50% SLA | 高利用概率 |
| 一级（核心）资产 | -25% SLA | 最大业务影响 |
| 补偿控制已到位 | +25% SLA | 风险已部分降低 |
| 供应商补丁尚不可用 | 例外处理并设置审查日期 | 暂时无法修复 |

### 关键绩效指标（KPI）

| KPI | 计算公式 | 目标 |
|-----|---------|--------|
| 平均修复时间（MTTR） | 平均值（修复日期 - 发现日期） | 整体 < 30 天 |
| SLA 合规率 | （在 SLA 内修复的漏洞数 / 总漏洞数）* 100 | >= 90% |
| 超期漏洞数量 | 计数（年龄 > SLA）条目 | 持续下降趋势 |
| 漏洞老化分布 | 按年龄段计数（0-14 天、15-30 天、31-60 天、60+ 天） | 大多数在 0-30 天 |
| 修复速度 | 每周关闭的漏洞数 | 持续上升趋势 |
| 例外率 | （例外数 / 总漏洞数）* 100 | < 5% |

## 实施步骤

### 步骤 1：制定 SLA 策略文件

```
漏洞修复 SLA 策略 v1.0

1. 范围：所有信息系统和应用程序
2. 严重性分类：基于 CVSS v4.0/v3.1 基础评分
3. SLA 时间线：参见标准 SLA 框架表
4. 自适应调节系数：根据资产背景应用
5. 例外流程：
   - 必须记录业务理由
   - 需要补偿控制描述
   - 最长延期：90 天（可续期一次）
   - 关键/高危例外需要 CISO 批准
6. 升级路径：
   - SLA 已过 50%：向资产负责人发送自动提醒
   - SLA 已过 75%：升级至经理
   - SLA 已过 100%（超期）：CISO 通知
   - SLA 已过 120%：VP/CTO 升级
7. 指标报告：每月向安全委员会报告
```

### 步骤 2：构建老化计算引擎

```python
import pandas as pd
from datetime import datetime, timedelta

class VulnerabilityAgingTracker:
    """跟踪漏洞老化和 SLA 合规情况。"""

    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):
        """计算每个漏洞的老化指标。"""
        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):
        """从老化数据生成 KPI 摘要。"""
        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):
        """获取需要升级的漏洞列表。"""
        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 升级"
            elif pct >= 100:
                level = "CISO 通知"
            elif pct >= 75:
                level = "经理升级"
            elif pct >= 50:
                level = "负责人提醒"
            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：仪表盘可视化

```python
# Grafana/Kibana 漏洞老化查询示例

# 老化分布直方图（Elasticsearch）
age_distribution_query = {
    "aggs": {
        "age_buckets": {
            "range": {
                "field": "age_days",
                "ranges": [
                    {"key": "0-7 天", "to": 8},
                    {"key": "8-14 天", "from": 8, "to": 15},
                    {"key": "15-30 天", "from": 15, "to": 31},
                    {"key": "31-60 天", "from": 31, "to": 61},
                    {"key": "61-90 天", "from": 61, "to": 91},
                    {"key": "90+ 天", "from": 91},
                ]
            }
        }
    }
}

# SLA 合规趋势（按月）
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"
                    }}
                }
            }
        }
    }
}
```

## 最佳实践

1. 从可实现的 SLA 目标开始，随着流程成熟逐步收紧
2. 根据资产关键性和威胁背景调整 SLA，而不仅仅依赖 CVSS 评分
3. 自动化升级通知以减少手动跟踪开销
4. 按月跟踪 MTTR 趋势以展示改进成果
5. 构建需要记录补偿控制的例外工作流
6. 每月向高管层报告 SLA 合规情况以确保问责制
7. 在安全委员会和董事会级别报告中包含老化指标
8. 将 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

