[安全教育] 002 資安 KPI 怎麼定?用數據證明安全投資的價值|關鍵指標與成效追蹤實戰指南

「沒有度量,就沒有改進。沒有改進,就沒有信任。
你花了三個月導入 SSDLC,老闆問你『成效在哪?』——你拿得出數據嗎?
安全不只要做得好,還要讓人看得見。」
— SSDLC by 飛飛


一、資安指標是什麼?為什麼你需要一張「安全體檢報告」?

在 SSDLC 蓋房子的旅程中,我們已經走過了安全需求(確認要防震防火防盜)、安全設計(畫好建築藍圖)、安全開發(用防火建材施工)、安全測試(請結構技師來驗收)、安全部署(交屋前檢查門窗設定)、安全維運(裝好監視器和煙霧偵測器)。現在,我們來到了階段七:安全教育與持續改進(Education & Continuous Improvement)——如何用數據衡量這一切努力的成果。

想像你花了一大筆錢把房子全面翻修:換了防盜門窗、裝了消防灑水系統、加了監視器和保全。然後你老婆問你:「花了這些錢,到底有沒有比較安全?」

你說:「有啊,感覺比較安全了。」

她說:「什麼叫『感覺』?給我看數據。」

這就是資安指標在做的事——把「感覺比較安全」變成「可以證明比較安全」

在企業裡,這個場景更加現實:你向老闆申請了 NT$50 萬的資安預算,導入了 SAST 掃描、買了 DAST 工具、送工程師去上資安課程。年底績效評估時,老闆問:「這 50 萬花得值嗎?明年還要繼續投嗎?」

如果你只能回答「呃,我們比較安全了」,那明年的預算大概率會被砍。但如果你能拿出一張報告:

  • 高風險漏洞從上線前平均 12 個降到 2 個
  • 漏洞修復時間從 14 天縮短到 3 天
  • 全年零資安事件,避免了預估 NT$500 萬的潛在損失

這就是用數據為安全投資背書,讓「安全」從成本中心變成價值中心。

飛飛觀點:
我曾經跟一位 CTO 聊天,他說:「資安就像買保險,花了錢如果沒出事,大家覺得浪費;出了事才後悔沒買。」資安指標就是解決這個困境的方法——讓安全的價值在「沒出事」的時候也能被量化、被看見。


二、傳統做法 vs. 數據驅動的安全管理

先來看看傳統做法和數據驅動做法的差別:

面向 傳統做法 數據驅動的安全管理
成效評估 「感覺比較安全了」 「高風險漏洞減少 83%」
預算申請 「我們需要更多資安投資」 「每投入 NT$1 在 SAST,省下 NT$8 的修復成本」
風險溝通 「系統可能有漏洞」 「目前有 3 個高風險漏洞,預估影響 2 萬名用戶」
改善方向 憑直覺決定 用數據找出最該投資的環節
向上報告 技術人員自己懂就好 管理層也能看懂的儀表板
團隊激勵 「大家要注意安全」 「這季的安全分數提升了 15 分,做得好!」

用蓋房子的比喻來說:

傳統做法就像裝修完房子後,問住戶「覺得怎麼樣?」——大家說「不錯啊」,但你不知道到底哪裡好、哪裡還需要加強。

數據驅動就像請驗屋師來出一份完整的檢測報告:結構強度 95 分、消防系統合格率 100%、門窗氣密性 88 分——你清楚知道整體狀況,也知道該把下一筆預算花在哪裡(氣密性)。


三、資安指標的兩大支柱:KPI 與 KRI

在進入具體指標之前,先搞清楚兩個核心概念:

KPI(Key Performance Indicator):關鍵績效指標

KPI 回答的問題是:「我們做得好不好?」

KPI 衡量的是你的安全措施的「成效」。就像學生的考試成績——用來評估學習效果、追蹤進步趨勢。

範例:

  • 漏洞修復時間(MTTR)是否在縮短?
  • CI/CD Pipeline 的安全掃描覆蓋率是否在提升?
  • 團隊的資安訓練完成率是多少?

KRI(Key Risk Indicator):關鍵風險指標

KRI 回答的問題是:「我們有多危險?」

KRI 衡量的是你的系統「當前面臨的風險水平」。就像體溫計——用來監測健康狀況,超標就要注意。

範例:

  • 目前有多少個未修補的高風險漏洞?
  • 過去 30 天發生了幾次安全事件?
  • 有多少個第三方套件存在已知 CVE?

KPI vs. KRI 的關係

面向 KPI(績效指標) KRI(風險指標)
回答什麼 我們做得好不好? 我們有多危險?
看的方向 回顧過去的表現 預警未來的風險
比喻 學生的期末成績 學生的健康檢查報告
目標 越高越好(或趨勢向好) 越低越好(或控制在閾值內)
範例 漏洞修復速度、訓練完成率 未修補漏洞數、暴露的攻擊面

飛飛觀點:
很多團隊只追蹤 KPI 卻忽略 KRI,就像只看考試成績卻不做健康檢查。成績再好,如果身體出問題也沒用。反過來說,只看 KRI 而不看 KPI,就像每天量體溫卻不運動——知道自己有風險,但不知道怎麼變好。兩者都要看,才是完整的資安成效追蹤。


四、關鍵安全指標清單:你的團隊應該追蹤什麼?

以下是我整理的資安指標體系,分為五大類別。不需要一次全做,後面會教你怎麼挑選最適合你的指標。

4.1 漏洞管理指標

這是最基本也最重要的一類指標,衡量你發現和修復漏洞的能力。

指標名稱 類型 計算方式 目標方向 說明
漏洞密度 KRI 漏洞數 / 千行程式碼(KLOC) ↓ 越低越好 程式碼的「安全品質密度」
高風險漏洞數 KRI CVSS ≥ 7.0 的未修補漏洞總數 ↓ 越低越好 當前的風險暴露程度
平均修復時間(MTTR) KPI 從發現到修復的平均天數 ↓ 越短越好 團隊的修復效率
修復率 KPI 已修復漏洞 / 已發現漏洞 × 100% ↑ 越高越好 漏洞是否有被處理
漏洞逃逸率 KPI 上線後才發現的漏洞 / 總漏洞數 × 100% ↓ 越低越好 開發階段的攔截能力
漏洞重開率 KPI 修復後又重現的漏洞 / 已修復漏洞 × 100% ↓ 越低越好 修復品質是否到位

台灣企業的合理目標參考:

指標 起步階段 成長階段 成熟階段
漏洞密度 < 10 / KLOC < 5 / KLOC < 2 / KLOC
高風險漏洞 MTTR < 30 天 < 14 天 < 7 天
中風險漏洞 MTTR < 90 天 < 30 天 < 14 天
漏洞逃逸率 < 30% < 15% < 5%

4.2 安全流程指標

衡量安全工具和流程的落實程度。

指標名稱 類型 計算方式 目標方向 說明
安全掃描覆蓋率 KPI 有跑安全掃描的 Repo / 總 Repo 數 × 100% ↑ 越高越好 CI/CD 安全整合的覆蓋程度
掃描通過率 KPI 通過安全品質門檻的 Build / 總 Build 數 × 100% ↑ 越高越好 程式碼品質的趨勢
安全審查率 KPI 經過安全審查的 PR / 總 PR 數 × 100% ↑ 越高越好 Code Review 中安全的涵蓋率
誤報率 KPI 確認為誤報的告警 / 總告警數 × 100% ↓ 越低越好 工具的精準度(太高會導致信任流失)
第三方套件漏洞比例 KRI 有已知 CVE 的套件 / 總套件數 × 100% ↓ 越低越好 供應鏈風險暴露程度

4.3 安全事件指標

衡量你的偵測和回應能力。

指標名稱 類型 計算方式 目標方向 說明
平均偵測時間(MTTD) KPI 從事件發生到被偵測的平均時間 ↓ 越短越好 監控系統的靈敏度
平均回應時間(MTTR) KPI 從偵測到開始處理的平均時間 ↓ 越短越好 事件回應的效率
安全事件數 KRI 過去 N 天/月的安全事件總數 ↓ 越低越好 整體安全態勢
事件復發率 KPI 同類型事件再次發生的比例 ↓ 越低越好 根因是否被徹底解決

4.4 人員與文化指標

衡量團隊的安全意識和能力。

指標名稱 類型 計算方式 目標方向 說明
資安訓練完成率 KPI 完成訓練的人數 / 應訓練人數 × 100% ↑ 越高越好 教育訓練的覆蓋率
Security Champion 覆蓋率 KPI 有 Champion 的團隊 / 總團隊數 × 100% ↑ 越高越好 安全文化的滲透程度
內部安全回報數 KPI 團隊成員主動回報的安全問題數 ↑ 越高越好 安全文化的健康度
安全知識評量分數 KPI 團隊在安全測驗中的平均分數 ↑ 越高越好 安全知識的實際掌握度

4.5 商業影響指標

讓管理層看得懂的指標,連結安全與商業價值。

指標名稱 類型 計算方式 目標方向 說明
安全修復成本節省 KPI 開發階段修復成本 vs. 上線後修復成本的差額 ↑ 越高越好 左移策略的經濟效益
因安全事件導致的停機時間 KRI 因資安事件導致的服務中斷總時數 ↓ 越低越好 安全對可用性的影響
合規差距數 KRI 未滿足法規要求的項目數 ↓ 越低越好 法規風險暴露程度
安全投資報酬率(ROSI) KPI (預期損失 – 實際損失 – 安全投資)/ 安全投資 × 100% ↑ 越高越好 安全投資的整體效益

五、實戰:用 Node.js 建立資安指標追蹤系統

讓我們用一個台灣電商平台的場景,從頭到尾建立一套資安指標追蹤系統。

5.1 定義度量資料結構

// security-metrics.js — 資安指標資料收集模組

/**
 * 資安指標的資料結構定義
 * 用於追蹤 SSDLC 各階段的安全成效
 */
const SecurityMetricsSchema = {
  // 報告基本資訊
  reportPeriod: {
    startDate: '2026-01-01',
    endDate: '2026-03-31',
    quarter: 'Q1-2026',
  },

  // 4.1 漏洞管理指標
  vulnerabilityMetrics: {
    totalDiscovered: 0,        // 本期發現的漏洞總數
    totalResolved: 0,          // 本期修復的漏洞總數
    openHighRisk: 0,           // 目前未修補的高風險漏洞
    openMediumRisk: 0,         // 目前未修補的中風險漏洞
    mttrHigh: 0,               // 高風險漏洞平均修復天數
    mttrMedium: 0,             // 中風險漏洞平均修復天數
    escapedToProduction: 0,    // 逃逸到正式環境的漏洞數
    reopened: 0,               // 修復後又重開的漏洞數
    densityPerKLOC: 0,         // 每千行程式碼的漏洞密度
  },

  // 4.2 安全流程指標
  processMetrics: {
    reposWithScanning: 0,      // 有安全掃描的 Repo 數
    totalRepos: 0,             // 總 Repo 數
    buildsPassed: 0,           // 通過安全門檻的 Build 數
    totalBuilds: 0,            // 總 Build 數
    prsWithSecurityReview: 0,  // 經安全審查的 PR 數
    totalPRs: 0,               // 總 PR 數
    falsePositives: 0,         // 誤報數
    totalAlerts: 0,            // 總告警數
    depsWithCVE: 0,            // 有已知 CVE 的套件數
    totalDeps: 0,              // 總套件數
  },

  // 4.3 安全事件指標
  incidentMetrics: {
    totalIncidents: 0,         // 安全事件總數
    mttdHours: 0,              // 平均偵測時間(小時)
    mttrHours: 0,              // 平均回應時間(小時)
    recurrentIncidents: 0,     // 復發的事件數
  },

  // 4.4 人員與文化指標
  cultureMetrics: {
    trainingCompleted: 0,      // 完成訓練的人數
    trainingRequired: 0,       // 應訓練的人數
    teamsWithChampion: 0,      // 有 Security Champion 的團隊數
    totalTeams: 0,             // 總團隊數
    internalReports: 0,        // 內部安全回報數
    avgQuizScore: 0,           // 安全測驗平均分數
  },
};

5.2 自動化資料收集

// collect-metrics.js — 從 CI/CD 工具自動收集度量資料
const { execSync } = require('child_process');

/**
 * 從 npm audit 收集依賴漏洞資料
 */
function collectDependencyMetrics(projectPath) {
  try {
    const auditResult = execSync(
      <code>cd ${projectPath} && npm audit --json 2>/dev/null</code>,
      { encoding: 'utf8' }
    );
    const audit = JSON.parse(auditResult);

    return {
      totalDeps: Object.keys(audit.vulnerabilities || {}).length,
      critical: countBySeverity(audit, 'critical'),
      high: countBySeverity(audit, 'high'),
      moderate: countBySeverity(audit, 'moderate'),
      low: countBySeverity(audit, 'low'),
      timestamp: new Date().toISOString(),
    };
  } catch (error) {
    console.error('npm audit 執行失敗:', error.message);
    return null;
  }
}

function countBySeverity(audit, severity) {
  return Object.values(audit.vulnerabilities || {})
    .filter(v => v.severity === severity).length;
}

/**
 * 從 Git 記錄計算程式碼行數(用於漏洞密度)
 */
function countLinesOfCode(projectPath) {
  try {
    // 使用 cloc 或簡單的 wc -l
    const result = execSync(
      <code>find ${projectPath}/src -name "*.js" -o -name "*.ts" | xargs wc -l | tail -1</code>,
      { encoding: 'utf8' }
    );
    const totalLines = parseInt(result.trim().split(/\s+/)[0], 10);
    return totalLines;
  } catch {
    return 0;
  }
}

/**
 * 計算漏洞密度
 */
function calculateVulnerabilityDensity(vulnCount, linesOfCode) {
  if (linesOfCode === 0) return 0;
  const kloc = linesOfCode / 1000;
  return parseFloat((vulnCount / kloc).toFixed(2));
}

/**
 * 從漏洞追蹤系統計算 MTTR(平均修復時間)
 * 假設使用 JSON 格式的漏洞記錄
 */
function calculateMTTR(vulnerabilities, severity = 'high') {
  const resolved = vulnerabilities
    .filter(v => v.severity === severity && v.resolvedAt)
    .map(v => {
      const discovered = new Date(v.discoveredAt);
      const resolved = new Date(v.resolvedAt);
      return (resolved - discovered) / (1000 * 60 * 60 * 24); // 天
    });

  if (resolved.length === 0) return 0;
  const avgDays = resolved.reduce((a, b) => a + b, 0) / resolved.length;
  return parseFloat(avgDays.toFixed(1));
}

module.exports = {
  collectDependencyMetrics,
  countLinesOfCode,
  calculateVulnerabilityDensity,
  calculateMTTR,
};

5.3 計算安全投資報酬率(ROSI)

這是讓老闆眼睛一亮的指標——用數字證明安全投資是划算的。

// rosi-calculator.js — 安全投資報酬率計算器

/**
 * ROSI(Return on Security Investment)計算
 *
 * 公式:ROSI = (預期年化損失 × 風險降低比例 - 安全投資成本) / 安全投資成本 × 100%
 *
 * 其中:
 * - ALE(Annualized Loss Expectancy)= SLE × ARO
 * - SLE(Single Loss Expectancy)= 單次事件的預估損失
 * - ARO(Annualized Rate of Occurrence)= 年化發生頻率
 */
function calculateROSI({
  singleLossExpectancy,   // 單次資安事件的預估損失(NT$)
  annualRateOfOccurrence, // 年化發生頻率(次/年)
  riskReductionRate,      // 導入安全措施後的風險降低比例(0-1)
  securityInvestment,     // 安全投資總成本(NT$)
}) {
  // 計算年化預期損失(ALE)
  const ale = singleLossExpectancy * annualRateOfOccurrence;

  // 計算導入安全措施後「避免的損失」
  const avoidedLoss = ale * riskReductionRate;

  // 計算 ROSI
  const rosi = ((avoidedLoss - securityInvestment) / securityInvestment) * 100;

  return {
    ale: Math.round(ale),
    avoidedLoss: Math.round(avoidedLoss),
    securityInvestment,
    rosi: parseFloat(rosi.toFixed(1)),
    netBenefit: Math.round(avoidedLoss - securityInvestment),
  };
}

// ============================
// 實際案例:台灣電商平台
// ============================

const ecommerceCase = calculateROSI({
  // 一次資料外洩事件的預估損失
  // 包含:罰鍰 + 客戶流失 + 法律費用 + 商譽損失
  singleLossExpectancy: 5000000,   // NT$500 萬

  // 根據產業統計,類似規模的電商平台
  // 每年發生重大資安事件的頻率約 0.3 次
  annualRateOfOccurrence: 0.3,

  // 導入 SSDLC(SAST + SCA + DAST + 教育訓練)後
  // 預估可降低 70% 的風險
  riskReductionRate: 0.7,

  // 年度安全投資
  // SAST 工具:NT$0(使用開源 Semgrep)
  // DAST 工具:NT$0(使用開源 ZAP)
  // 教育訓練:NT$100,000
  // 一次滲透測試:NT$250,000
  // 工程師時間成本:NT$150,000
  securityInvestment: 500000,      // NT$50 萬
});

console.log('=== 台灣電商平台 ROSI 分析 ===');
console.log(<code class="kb-btn">年化預期損失 (ALE):NT$${ecommerceCase.ale.toLocaleString()}</code>);
console.log(<code class="kb-btn">避免的損失:NT$${ecommerceCase.avoidedLoss.toLocaleString()}</code>);
console.log(<code class="kb-btn">安全投資:NT$${ecommerceCase.securityInvestment.toLocaleString()}</code>);
console.log(<code class="kb-btn">淨效益:NT$${ecommerceCase.netBenefit.toLocaleString()}</code>);
console.log(<code>ROSI:${ecommerceCase.rosi}%</code>);

// 輸出:
// === 台灣電商平台 ROSI 分析 ===
// 年化預期損失 (ALE):NT$1,500,000
// 避免的損失:NT$1,050,000
// 安全投資:NT$500,000
// 淨效益:NT$550,000
// ROSI:110%
// → 每投入 NT$1,產生 NT$1.10 的安全效益

飛飛觀點:
ROSI 不是精確的科學計算,而是一種「合理的估算」。重點不在於數字是否 100% 精確,而在於它提供了一個讓技術人員和管理層能夠「講同一種語言」的框架。當老闆問「為什麼要花這筆錢」,你能拿出一個有邏輯的數字,而不是只說「因為安全很重要」——這就夠了。

5.4 漏洞修復成本的「左移效益」

IBM 在其年度《資料外洩成本報告》中長年追蹤一個重要發現:漏洞越早發現,修復成本越低。以下是根據業界研究整理的相對成本:

// shift-left-cost.js — 左移策略的成本效益計算

/**
 * 不同階段發現漏洞的相對修復成本
 * 基準:需求階段 = 1x
 */
const RELATIVE_COST = {
  requirements: 1,    // 需求階段(寫規格時發現)
  design: 5,          // 設計階段(威脅建模時發現)
  implementation: 10, // 實作階段(Code Review / SAST 發現)
  testing: 15,        // 測試階段(DAST / 滲透測試發現)
  production: 30,     // 正式環境(上線後才發現)
  breach: 100,        // 資料外洩事件(被攻擊後才發現)
};

/**
 * 計算左移策略的成本節省
 */
function calculateShiftLeftSavings({
  vulnsFoundInRequirements,
  vulnsFoundInDesign,
  vulnsFoundInImplementation,
  vulnsFoundInTesting,
  vulnsFoundInProduction,
  baseCostPerVuln,  // 需求階段修復一個漏洞的基本成本(NT$)
}) {
  // 如果所有漏洞都在正式環境才發現的「最差情境」成本
  const totalVulns =
    vulnsFoundInRequirements +
    vulnsFoundInDesign +
    vulnsFoundInImplementation +
    vulnsFoundInTesting +
    vulnsFoundInProduction;

  const worstCaseCost = totalVulns * baseCostPerVuln * RELATIVE_COST.production;

  // 實際成本(在不同階段發現)
  const actualCost =
    vulnsFoundInRequirements * baseCostPerVuln * RELATIVE_COST.requirements +
    vulnsFoundInDesign * baseCostPerVuln * RELATIVE_COST.design +
    vulnsFoundInImplementation * baseCostPerVuln * RELATIVE_COST.implementation +
    vulnsFoundInTesting * baseCostPerVuln * RELATIVE_COST.testing +
    vulnsFoundInProduction * baseCostPerVuln * RELATIVE_COST.production;

  return {
    totalVulns,
    worstCaseCost: Math.round(worstCaseCost),
    actualCost: Math.round(actualCost),
    savings: Math.round(worstCaseCost - actualCost),
    savingsPercentage: parseFloat(
      (((worstCaseCost - actualCost) / worstCaseCost) * 100).toFixed(1)
    ),
  };
}

// 實際案例:某台灣金融科技公司的季度數據
const result = calculateShiftLeftSavings({
  vulnsFoundInRequirements: 3,    // 安全規格審查時發現 3 個
  vulnsFoundInDesign: 5,          // 威脅建模時發現 5 個
  vulnsFoundInImplementation: 12, // SAST / Code Review 發現 12 個
  vulnsFoundInTesting: 4,         // DAST / 滲透測試發現 4 個
  vulnsFoundInProduction: 1,      // 上線後才發現 1 個
  baseCostPerVuln: 5000,          // 需求階段修復一個漏洞約 NT$5,000
});

console.log('=== 左移效益分析 ===');
console.log(<code>總漏洞數:${result.totalVulns} 個</code>);
console.log(<code class="kb-btn">最差情境成本(全在線上發現):NT$${result.worstCaseCost.toLocaleString()}</code>);
console.log(<code class="kb-btn">實際成本(左移後):NT$${result.actualCost.toLocaleString()}</code>);
console.log(<code class="kb-btn">節省金額:NT$${result.savings.toLocaleString()}</code>);
console.log(<code>節省比例:${result.savingsPercentage}%</code>);

// 輸出:
// === 左移效益分析 ===
// 總漏洞數:25 個
// 最差情境成本(全在線上發現):NT$3,750,000
// 實際成本(左移後):NT$620,000
// 節省金額:NT$3,130,000
// 節省比例:83.5%

六、資安成效報告模板:可直接使用的季度報告

以下是一份完整的資安成效季度報告模板,你可以直接拿來用:

# 資安成效季度報告

## 報告資訊
- **報告期間**:2026 年 Q1(1 月 - 3 月)
- **報告日期**:2026/04/05
- **編製人**:[Security Champion 姓名]
- **審核人**:[技術主管姓名]

---

## 一、執行摘要(給管理層看的 30 秒版本)

本季安全態勢整體**改善**,主要亮點:
- ✅ 高風險漏洞修復時間從 21 天縮短至 7 天(改善 67%)
- ✅ CI/CD 安全掃描覆蓋率從 60% 提升至 85%
- ✅ 全季零重大安全事件
- ⚠️ 第三方套件漏洞比例偏高(12%),需加速更新

**安全投資效益**:本季安全投資 NT$150,000,預估避免損失 NT$500,000,ROSI 為 233%。

---

## 二、漏洞管理

| 指標 | 上季 | 本季 | 趨勢 | 目標 |
|------|------|------|------|------|
| 漏洞密度(/ KLOC) | 4.2 | 3.1 | ↓ 改善 | < 2.0 |
| 未修補高風險漏洞 | 5 | 2 | ↓ 改善 | 0 |
| 高風險 MTTR(天) | 21 | 7 | ↓ 改善 | < 7 |
| 中風險 MTTR(天) | 45 | 18 | ↓ 改善 | < 14 |
| 漏洞逃逸率 | 18% | 8% | ↓ 改善 | < 5% |
| 漏洞重開率 | 10% | 5% | ↓ 改善 | < 3% |

**分析**:SAST 工具(Semgrep)在 Q1 初導入後,顯著提升了開發階段的攔截能力,
漏洞逃逸率下降 10 個百分點。

---

## 三、安全流程

| 指標 | 上季 | 本季 | 趨勢 | 目標 |
|------|------|------|------|------|
| 安全掃描覆蓋率 | 60% | 85% | ↑ 改善 | 100% |
| 掃描通過率 | 72% | 81% | ↑ 改善 | > 90% |
| 安全審查率 | 30% | 55% | ↑ 改善 | > 80% |
| 誤報率 | 25% | 18% | ↓ 改善 | < 10% |
| 有 CVE 的套件比例 | 15% | 12% | ↓ 改善 | < 5% |

---

## 四、安全事件

| 指標 | 上季 | 本季 | 趨勢 |
|------|------|------|------|
| 安全事件總數 | 3 | 0 | ↓ 改善 |
| P1/P2 事件 | 1 | 0 | ↓ 改善 |
| MTTD(小時) | 48 | N/A | - |
| MTTR(小時) | 72 | N/A | - |

---

## 五、人員與文化

| 指標 | 上季 | 本季 | 趨勢 | 目標 |
|------|------|------|------|------|
| 資安訓練完成率 | 40% | 75% | ↑ 改善 | 100% |
| Security Champion 覆蓋率 | 25% | 50% | ↑ 改善 | 100% |
| 內部安全回報數 | 2 | 7 | ↑ 改善 | 持續增加 |

---

## 六、下季行動計畫

| 優先序 | 行動項目 | 負責人 | 預計完成日 |
|--------|---------|--------|-----------|
| P1 | 安全掃描覆蓋率提升至 100% | DevOps Lead | Q2 第 2 週 |
| P1 | 處理剩餘 2 個高風險漏洞 | 後端團隊 | Q2 第 1 週 |
| P2 | 第三方套件全面更新 | 各團隊 Champion | Q2 第 4 週 |
| P2 | 調整 SAST 規則降低誤報率 | 資安 Champion | Q2 第 6 週 |
| P3 | 全員資安訓練達 100% | HR + 資安 | Q2 第 8 週 |

飛飛觀點:
報告最重要的不是「有多少頁」,而是「前 30 秒能不能讓人看懂」。管理層通常只看執行摘要——所以那一段要用最簡潔的方式傳達「現在安全嗎?」和「錢花得值嗎?」兩個核心問題。詳細數據是給技術團隊深入分析用的。


七、用 OWASP SAMM 評估安全成熟度

除了追蹤單一指標,你也需要一個「全局視角」來評估團隊的安全開發成熟度。OWASP SAMM(Software Assurance Maturity Model) 就是這樣的工具。

SAMM 是什麼?

SAMM 把安全開發分成 5 個業務功能、15 個安全實務,每個實務有 3 個成熟度等級。你可以用它來:

  1. 評估現況:我們現在在哪裡?
  2. 設定目標:我們想達到什麼水準?
  3. 追蹤進步:我們有沒有在進步?

SAMM 五大業務功能

業務功能 說明 包含的安全實務
治理(Governance) 管理和策略 策略與指標、政策與合規、教育與指導
設計(Design) 威脅評估和架構 威脅評估、安全需求、安全架構
實作(Implementation) 建構和部署 安全建構、安全部署、缺陷管理
驗證(Verification) 測試和審查 架構評估、需求驗證測試、安全測試
營運(Operations) 事件和環境 事件管理、環境管理、營運管理

成熟度等級

等級 說明 比喻
Level 0 沒有做 房子沒裝門鎖
Level 1 有基本做法,但非系統化 有裝門鎖,但沒有保全系統
Level 2 有系統化的流程 有保全系統,定期巡邏
Level 3 全面優化,持續改進 24 小時監控中心,定期演練

快速自評 Checklist

以下是一份簡化版的 SAMM 自評表,適合作為團隊的第一次評估:

## OWASP SAMM 快速自評 Checklist

### 治理(Governance)
- [ ] Level 1: 有基本的安全政策文件
- [ ] Level 1: 團隊成員接受過安全教育訓練
- [ ] Level 2: 有定義資安 KPI 並定期追蹤
- [ ] Level 2: 安全政策每年審查更新
- [ ] Level 3: 安全策略與業務目標對齊,管理層定期審查

### 設計(Design)
- [ ] Level 1: 對高風險功能有做威脅建模
- [ ] Level 1: 有定義基本的安全需求
- [ ] Level 2: 所有新功能都有威脅建模
- [ ] Level 2: 有安全架構設計的標準和模式
- [ ] Level 3: 威脅建模結果被追蹤和驗證

### 實作(Implementation)
- [ ] Level 1: 有安全編碼規範
- [ ] Level 1: 有使用 SAST 工具
- [ ] Level 2: CI/CD 整合安全掃描
- [ ] Level 2: 有第三方套件漏洞管理流程
- [ ] Level 3: 安全品質門檻自動化,零容忍政策

### 驗證(Verification)
- [ ] Level 1: 有做過至少一次滲透測試
- [ ] Level 1: 有使用 DAST 工具
- [ ] Level 2: 定期執行安全測試(至少每季)
- [ ] Level 2: 安全測試涵蓋 OWASP Top 10
- [ ] Level 3: 安全測試完全自動化,結果追蹤到修復

### 營運(Operations)
- [ ] Level 1: 有基本的事件回應流程
- [ ] Level 1: 有安全監控和日誌
- [ ] Level 2: 有事件回應 SOP 和演練
- [ ] Level 2: 安全監控涵蓋應用層和基礎設施層
- [ ] Level 3: 自動化事件偵測和回應,定期紅隊演練

評分方式:

  • 每個 Level 的所有項目都勾選 → 達到該 Level
  • 取每個業務功能的最低達成 Level 作為該功能的分數
  • 5 個功能的平均值就是你的整體成熟度分數

八、安全儀表板設計:讓數據會說話

好的度量數據需要好的呈現方式。以下是安全儀表板的設計建議:

儀表板的三層結構

┌─────────────────────────────────────────────────────────────┐
│                    Layer 1:執行摘要                          │
│  給 CTO/CEO 看的,一眼就知道「安全嗎?」                      │
│                                                              │
│  🟢 安全態勢:良好    📊 ROSI:110%    ⚠️ 待處理:2 個高風險  │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│                    Layer 2:趨勢分析                          │
│  給技術主管看的,了解「有沒有在進步?」                        │
│                                                              │
│  📈 漏洞密度趨勢(過去 4 季)                                 │
│  📉 MTTR 趨勢(過去 4 季)                                   │
│  📊 安全掃描覆蓋率趨勢                                       │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│                    Layer 3:詳細數據                          │
│  給資安團隊看的,深入分析「哪裡需要改進?」                    │
│                                                              │
│  🔍 個別漏洞清單與狀態                                       │
│  📋 各 Repo 的掃描結果                                       │
│  👥 各團隊的訓練完成度                                        │
└─────────────────────────────────────────────────────────────┘

安全態勢的紅綠燈系統

用簡單的紅黃綠燈讓所有人一眼看懂:

燈號 條件 代表意義
🟢 綠燈 所有高風險漏洞已修復 + 掃描覆蓋率 > 80% + 本月零事件 安全態勢良好
🟡 黃燈 有 1-3 個高風險漏洞待修復,或覆蓋率 < 80% 需要關注
🔴 紅燈 有 > 3 個高風險漏洞,或發生 P1/P2 事件 需要立即行動

九、團隊落地建議:從零開始建立資安指標追蹤

建議一:從三個指標開始

如果你的團隊從來沒追蹤過資安指標,不要一口氣追蹤 20 個指標——那只會讓大家疲於奔命。先從這三個最基本的開始:

  1. 高風險漏洞數量(KRI)— 知道你現在有多危險
  2. 高風險漏洞 MTTR(KPI)— 知道你修得夠不夠快
  3. 安全掃描覆蓋率(KPI)— 知道你有沒有在做安全檢查

這三個指標就像體檢的血壓、血糖、心率——最基本但最關鍵。

建議二:善用現有工具自動收集

不需要另外買度量工具。你的 CI/CD 系統已經有很多數據:

資料來源 可以提取的指標
GitHub / GitLab PR 數、Code Review 數、Merge 時間
npm audit / Snyk 套件漏洞數、嚴重等級分布
Semgrep / SonarQube 程式碼漏洞數、漏洞密度
OWASP ZAP DAST 掃描結果、漏洞類別分布
Jira / Linear 漏洞修復時間、漏洞狀態追蹤
Slack / Teams 安全事件通報數、回應時間

建議三:每季做一次資安成效報告

不需要每天看數字,但至少每季做一次正式的回顧:

每季資安指標追蹤流程:

第 1 週:自動化收集數據
    ↓
第 2 週:分析趨勢,撰寫報告
    ↓
第 3 週:團隊內部 Review
    ↓
第 4 週:向管理層報告,設定下季目標
    ↓
  (下一季重複)

建議四:把度量結果跟團隊目標連結

度量不是為了懲罰,而是為了改進。把資安指標融入團隊的 OKR 或 KPI:

## 範例:工程團隊 Q2 OKR

**Objective:提升產品安全品質**

KR1:高風險漏洞 MTTR 從 14 天降至 7 天
KR2:CI/CD 安全掃描覆蓋率達 100%
KR3:漏洞逃逸率從 15% 降至 8%
KR4:全員完成 OWASP Top 10 線上課程

建議五:慶祝進步,不懲罰失敗

這是安全文化的核心。當指標改善時,公開表揚團隊。當指標退步時,把它當作學習機會,不是指責對象。

  • ✅ 「這季的 MTTR 縮短了 50%,大家做得很好!」
  • ✅ 「漏洞逃逸率上升了,我們來看看是哪個環節需要加強。」
  • ❌ 「誰寫的程式碼又出問題了?」

常見問題 FAQ

Q1:我們公司很小(3-5 人團隊),有必要追蹤資安指標嗎?

有,但可以極度簡化。小團隊只需要追蹤三個數字:目前有幾個高風險漏洞、修一個漏洞平均要多久、CI/CD 有沒有跑安全掃描。每個月花 15 分鐘看一下就好。重點不是做出一份精美的報告,而是養成「用數據看安全」的習慣。

Q2:ROSI 的數據很難估算,有什麼簡化方法?

可以用「事件成本法」來簡化:找出過去一年你們產業中類似規模公司發生資安事件的案例,估算一次事件的平均成本(包括停機、修復、客戶流失、罰鍰)。台灣中小型電商的一次資料外洩事件平均損失在 NT$200 萬到 NT$1,000 萬之間,金融業更高。拿這個數字乘以你認為的年化發生頻率(通常 0.1-0.5),就是你的 ALE。不需要追求精確,合理的估算就夠了。

Q3:安全指標一直沒改善怎麼辦?

先檢查三件事:一是指標本身是否合理——目標太高會讓團隊挫敗,建議一次只改善一個指標;二是工具是否到位——光靠人力很難提升指標,自動化工具是必要的投資;三是是否有明確的負責人——沒人負責的指標不會自己變好。如果三件事都確認了,還是沒進步,可能需要重新檢視你的安全流程設計。

Q4:管理層對資安成效報告沒興趣怎麼辦?

把報告「翻譯」成他們在意的語言。管理層不在意漏洞密度是 3.1 還是 4.2,但他們在意:「如果不處理這些漏洞,一旦發生資料外洩,可能面臨 NT$500 萬的罰鍰和客戶流失。」「這季的安全投資為公司避免了 NT$100 萬的潛在損失。」用風險和金錢說話,比用技術術語有效 10 倍。


十、結語:量化安全,讓努力被看見

回到蓋房子的比喻。你花了大量心血學習安全需求、安全設計、安全編碼、安全測試、安全監控——這一路走來,你的房子已經從一棟普通的建築,變成了一座有防震結構、消防系統、監視保全的安全堡壘。

但最終,你需要一份「驗屋報告」,證明這些努力不是白費的。資安指標就是那份報告。

它不只是給老闆看的——更是給你自己和團隊看的。當你看到漏洞密度從 10 降到 3,當你看到 MTTR 從一個月縮短到一週,當你看到安全掃描覆蓋率從 0% 爬到 100%——每一個數字的改善,都是你和團隊一步一步踏實走出來的成果。

「安全不是恐懼,而是創造的基礎。而度量,就是讓你看見自己走了多遠、還能走多遠的地圖。」

SSDLC 的七個階段,我們一路從安全需求走到了資安成效追蹤。這不是終點,而是一個新的循環的起點。有了度量,你才知道下一輪要從哪裡開始改進;有了數據,你才能持續讓安全變得更好。

記住,沒有度量的安全是盲目的努力,而有度量的安全是持續進化的力量。

讓我們用數據,讓安全的價值被每一個人看見。


延伸閱讀