[安全維運] 002 事件回應 SOP 完整指南:發生資安事件怎麼辦?NIST 四階段流程與 Node.js 實戰範例
「房子住進去之後,最怕的不是牆壁裂開,而是半夜火災時不知道滅火器在哪裡。
系統上線之後也一樣——你不怕出事,怕的是出事之後手忙腳亂、沒有人知道該做什麼。
事件回應不是『希望用不到』的東西,而是『用到時能救命』的東西。」
— SSDLC by 飛飛
一、事件回應是什麼?為什麼每個開發團隊都需要一份 SOP?
想像你住在一棟新蓋好的公寓裡。建商用了防火建材、裝了煙霧偵測器、也有消防灑水系統。這些都是之前在設計和施工階段做好的安全措施。
但有一天,三樓真的冒煙了。
這時候你需要的不是再去研究防火建材的規格,而是:
- 誰負責打 119?
- 住戶要從哪個樓梯逃生?
- 消防栓在幾樓?
- 怎麼確認所有人都安全撤離了?
- 火滅了之後,要怎麼評估損失、修復房屋?
這就是事件回應(Incident Response, IR)——當資安事件真的發生時,你的團隊要按照什麼流程來處理,才能把傷害降到最低、盡快恢復正常。
在 SSDLC 的旅程中,我們已經走過了安全需求(確認要防火)、安全設計(畫好消防通道)、安全實作(裝好偵測器)、安全驗證(測試灑水系統能不能動)。現在我們來到了階段五:部署與維運——房子住進去之後,真的發生狀況要怎麼辦?
為什麼這件事這麼重要?
因為不管你的防禦做得多好,沒有任何系統是 100% 不會被入侵的。就像不管防火建材多好,你還是需要滅火器和逃生計畫。資安界有句名言:
「被入侵不是『會不會』的問題,而是『什麼時候』的問題。」
根據 IBM 的統計,擁有事件回應計畫並定期演練的組織,平均每次資料外洩事件可以節省超過 NT$5,000 萬的損失。不是因為他們不會被攻擊,而是因為他們知道被攻擊後該怎麼做。
二、事件回應的四大階段:用火災應變來理解
事件回應有一個經典的框架,來自 NIST SP 800-61(Computer Security Incident Handling Guide)。它把事件回應分成四個階段,我們繼續用公寓火災的比喻來理解:
┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 🛡️ 階段一 │───▶│ 🔍 階段二 │───▶│ 🔧 階段三 │───▶│ 📝 階段四 │
│ 準備 │ │ 偵測與分析 │ │ 封鎖、消除 │ │ 事後活動 │
│ Preparation │ │ Detection & │ │ 與復原 │ │ Post- │
│ │ │ Analysis │ │ Containment │ │ Incident │
│ │ │ │ │ Eradication │ │ Activity │
│ │ │ │ │ & Recovery │ │ │
│ 🏠 準備好 │ │ 🏠 發現冒煙 │ │ 🏠 滅火+ │ │ 🏠 檢討+ │
│ 滅火器和 │ │ 確認是火災 │ │ 修復+ │ │ 改進 │
│ 逃生計畫 │ │ 還是燒焦味 │ │ 重新入住 │ │ 防災措施 │
└──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘
│ │
└──────────────────────────────────────────────────────────┘
持續改善的循環
這四個階段形成一個循環,每次處理完事件的經驗,都會回饋到準備階段,讓下一次的應變更好。
階段一:準備(Preparation)——滅火器要在火災前就買好
公寓比喻:在火災發生之前,你要做的事:
- 買滅火器放在走廊
- 畫好逃生路線圖貼在電梯旁
- 確認所有住戶都知道逃生出口在哪
- 跟管委會確認消防公司的電話
- 每半年做一次消防演練
在資安領域,準備階段要做這些事:
1. 組建事件回應團隊(CSIRT)
CSIRT(Computer Security Incident Response Team)就是你的「消防隊」。不需要是專職的資安團隊,但每個角色必須明確:
| 角色 | 職責 | 公寓比喻 |
|---|---|---|
| 事件指揮官(Incident Commander) | 統籌整個事件處理流程,做最終決策 | 管委會主委 |
| 技術負責人(Technical Lead) | 帶領技術調查與修復 | 水電師傅 |
| 溝通聯絡人(Communications Lead) | 對內對外溝通,包含通知客戶、主管機關 | 總幹事 |
| 法務/合規(Legal/Compliance) | 確認法規通報義務、保存證據 | 社區法律顧問 |
| 管理層代表(Management) | 核准重大決策(如關閉系統) | 建設公司代表 |
飛飛觀點:
對於 5-10 人的小團隊,不需要每個角色都是不同的人。CTO 可以同時是事件指揮官和技術負責人,PM 可以兼溝通聯絡人。重點是事先指定,而不是事發後才在群組裡問「誰來處理?」
2. 準備工具與資源
就像滅火器要在火災前就放好,以下工具要在事件發生前就準備好:
□ 日誌集中管理系統(如 ELK Stack、Graylog)
□ 系統監控與告警工具(如 Grafana、CloudWatch)
□ 事件追蹤系統(如 Jira、PagerDuty)
□ 安全的溝通管道(不要用可能被入侵的系統來討論事件!)
□ 數位鑑識工具(如 Volatility、Autopsy)
□ 離線備份(確認備份真的可以還原)
□ 聯絡清單(團隊成員手機、外部資安廠商、主管機關聯繫方式)
3. 建立事件分類與分級標準
不是每個告警都是世界末日。你需要一套分級標準,讓團隊知道什麼時候該全員召集、什麼時候看一下就好:
| 等級 | 名稱 | 說明 | 回應時效 | 範例 |
|---|---|---|---|---|
| P1 | 緊急(Critical) | 系統核心功能受損或大規模資料外洩 | 15 分鐘內回應 | 資料庫被拖走、勒索軟體感染 |
| P2 | 高(High) | 部分功能受影響或有確認的入侵跡象 | 1 小時內回應 | 管理後台被未授權存取、異常大量 API 呼叫 |
| P3 | 中(Medium) | 可疑活動但尚未確認影響 | 4 小時內回應 | 多次登入失敗、可疑的掃描行為 |
| P4 | 低(Low) | 資訊性事件,需要記錄但不需緊急處理 | 下一個工作日 | 弱點掃描發現低風險問題 |
4. 定期演練
有逃生計畫但從來不演練,等真的火災來了,大家還是會慌。建議每季做一次桌上演練(Tabletop Exercise)——不需要真的動系統,團隊坐下來,模擬一個資安事件情境,走一遍流程。
演練情境範例(台灣電商場景):
情境:你們的電商平台在週五晚上 10 點收到客戶投訴,
說他的帳號被用來下了一筆 NT$50,000 的訂單,但他本人沒有操作。
同時,監控系統顯示過去 1 小時有超過 500 個帳號從同一個 IP 段嘗試登入,
其中 30 個帳號登入成功。
請討論:
1. 這是什麼等級的事件?
2. 誰應該被通知?
3. 第一步要做什麼?
4. 需要通報主管機關嗎?(提示:個資法)
5. 要不要暫時關閉登入功能?
階段二:偵測與分析(Detection & Analysis)——確認是真的火災,還是只是鄰居在烤肉
公寓比喻:煙霧偵測器響了,你要先搞清楚:
- 是真的失火了嗎?還是有人在廚房燒焦了東西?
- 如果是火災,火源在哪?幾樓?
- 範圍多大?有擴散嗎?
- 有沒有人受傷?
在資安領域,偵測與分析要回答這些問題:
1. 事件來源有哪些?
資安事件的「煙霧偵測器」有很多種:
| 偵測來源 | 說明 | 範例 |
|---|---|---|
| 監控系統告警 | SIEM、IDS/IPS 發出的自動告警 | 「同一 IP 在 5 分鐘內嘗試登入 200 次」 |
| 使用者回報 | 客戶或內部員工通報 | 「我的帳號被盜了」「網站出現奇怪的頁面」 |
| 第三方通知 | 外部資安研究者或合作夥伴告知 | 「在暗網看到你們的客戶資料在賣」 |
| 例行檢查 | 定期的日誌審查或掃描 | 「弱點掃描發現新的 Critical 弱點」 |
| 執法機關通知 | 警察或調查局告知 | 「你們的系統IP出現在犯罪調查中」 |
2. 初步分析:確認事件的真實性與範圍
收到告警後,不要馬上恐慌。先做初步分析:
// 事件初步分析 Checklist(Node.js 日誌查詢範例)
const analyzeIncident = async (alertData) => {
console.log('=== 事件初步分析 ===');
// 1. 確認告警來源是否可信
console.log('📌 告警來源:', alertData.source);
console.log('📌 告警時間:', alertData.timestamp);
// 2. 查詢相關日誌
const relatedLogs = await queryLogs({
timeRange: {
start: new Date(alertData.timestamp - 3600000), // 往前看 1 小時
end: new Date(alertData.timestamp + 1800000), // 往後看 30 分鐘
},
filters: {
sourceIP: alertData.sourceIP,
userId: alertData.userId,
}
});
// 3. 初步判斷
const analysis = {
isConfirmed: false, // 是否確認為真實事件
severity: 'UNKNOWN', // 嚴重等級
affectedSystems: [], // 受影響的系統
affectedUsers: 0, // 受影響的使用者數量
dataExposure: 'UNKNOWN', // 是否有資料外洩
isOngoing: true, // 攻擊是否仍在進行
};
// 4. 記錄分析結果(保留證據!)
await saveToIncidentLog({
incidentId: generateIncidentId(), // IR-2026-001
analyst: 'on-call-engineer',
timestamp: new Date(),
findings: analysis,
rawLogs: relatedLogs,
});
return analysis;
};
3. 事件時間線建立
確認是真實事件後,最重要的事情之一就是建立事件時間線(Timeline)。這就像火災調查員會重建火災的發展過程:
📅 事件時間線範例:帳號大規模盜用事件
2026-02-27 21:30 監控系統偵測到異常登入行為
(同一 IP 段 103.xx.xx.0/24 大量登入嘗試)
2026-02-27 21:45 告警發送至 on-call 工程師
2026-02-27 21:50 工程師確認為 Credential Stuffing 攻擊
(撞庫攻擊,使用外洩的帳密清單嘗試登入)
2026-02-27 22:00 第一位客戶來電投訴帳號被盜
2026-02-27 22:10 初步統計:30 個帳號被成功登入
其中 5 個帳號已被用來下單
2026-02-27 22:15 升級為 P1 事件,通知事件指揮官
2026-02-27 22:20 ▶ 進入階段三:封鎖與消除
飛飛觀點:
時間線是事件回應中最有價值的產出之一。它不只是事後寫報告用的,在事件處理過程中,它能幫助你的團隊保持頭腦清醒——在壓力下,人很容易忘記自己做了什麼、什麼時間做的。養成習慣,每做一個動作就記一筆。
階段三:封鎖、消除與復原(Containment, Eradication & Recovery)——滅火、清理現場、重新入住
這是事件回應中最「動手」的階段。公寓比喻:
- 封鎖(Containment):先阻止火勢蔓延——關閉門窗、隔離起火樓層
- 消除(Eradication):把火撲滅、找到火源並確認完全熄滅
- 復原(Recovery):修復受損區域、確認安全後讓住戶回來
封鎖(Containment):先止血
封鎖的目標是阻止事件繼續擴大。分為短期封鎖和長期封鎖:
| 類型 | 目的 | 時機 | 範例 |
|---|---|---|---|
| 短期封鎖 | 立即止血,減少損害 | 確認事件後立即執行 | 封鎖攻擊來源 IP、停用被入侵帳號 |
| 長期封鎖 | 建立臨時防線,等待根本修復 | 短期封鎖後 | 啟用額外的認證機制、部署 WAF 規則 |
實戰範例:處理 Credential Stuffing 攻擊的封鎖措施
// 短期封鎖措施
const shortTermContainment = async (incidentData) => {
// 1. 封鎖攻擊來源 IP 段
await firewall.blockIPRange('103.xx.xx.0/24');
logAction('封鎖 IP 段 103.xx.xx.0/24');
// 2. 強制登出所有被入侵的帳號
for (const userId of incidentData.compromisedUsers) {
await session.revokeAllSessions(userId);
logAction(<code>強制登出使用者 ${userId} 所有 Session</code>);
}
// 3. 暫時提高登入的 Rate Limit
await rateLimiter.update({
endpoint: '/api/auth/login',
maxAttempts: 3, // 從 10 次降到 3 次
windowMinutes: 15, // 15 分鐘內
blockDuration: 60, // 超過就封鎖 60 分鐘
});
logAction('提高登入 Rate Limit 限制');
// 4. 凍結可疑訂單
for (const orderId of incidentData.suspiciousOrders) {
await orders.freeze(orderId);
logAction(<code class="kb-btn">凍結可疑訂單 ${orderId}</code>);
}
};
// 長期封鎖措施
const longTermContainment = async () => {
// 1. 對所有被入侵帳號強制重設密碼
for (const userId of incidentData.compromisedUsers) {
await auth.forcePasswordReset(userId);
await notification.send(userId, {
subject: '【重要】您的帳號安全通知',
template: 'account-compromised',
});
logAction(<code>強制重設使用者 ${userId} 密碼並發送通知</code>);
}
// 2. 部署 WAF 規則阻擋自動化攻擊
await waf.addRule({
name: 'block-credential-stuffing',
condition: 'login_failure_rate > 5/min per IP',
action: 'CAPTCHA_CHALLENGE',
});
logAction('部署 WAF Credential Stuffing 防護規則');
};
消除(Eradication):把火源徹底清除
封鎖只是「止血」,消除才是「治療」。你要找到根本原因並清除:
消除階段 Checklist:
□ 根本原因已確認
→ 此案例:使用者密碼來自其他平台的外洩資料,且未啟用 MFA
□ 攻擊者的存取路徑已關閉
→ 所有被入侵帳號已重設密碼
□ 攻擊者植入的後門已清除(如有)
→ 檢查是否有新增的 API Key、OAuth App、Webhook
□ 受影響的系統已修補
→ 新增 Credential Stuffing 防護機制
□ 相關的 IOC(Indicators of Compromise)已記錄
→ 攻擊 IP 段、攻擊模式特徵
復原(Recovery):確認安全後重新開放
復原不是「打開開關就好」,而是要逐步恢復、持續監控:
復原步驟:
1. ✅ 確認封鎖和消除措施都已到位
2. ✅ 在測試環境驗證修復方案
3. ✅ 逐步恢復服務(先灰度發布、再全量開放)
4. ✅ 加強監控(至少 72 小時高頻監控)
5. ✅ 確認被入侵帳號的使用者已收到通知
6. ✅ 確認可疑訂單已被正確處理(退款或確認)
飛飛觀點:
復原階段最常犯的錯誤就是「太急著恢復正常」。我見過有團隊在攻擊還沒完全消除的情況下就急著把系統打開,結果攻擊者馬上又進來了。寧可多花幾個小時確認,也不要讓同一個事件發生兩次。
階段四:事後活動(Post-Incident Activity)——火災之後的檢討與改善
火滅了、房子修好了、住戶回來了。但最重要的一步還沒做——從這次事件中學到什麼?
這個階段的核心就是無咎事後檢討會議(Blameless Postmortem)。
事後檢討會議的結構
建議在事件結束後 3-5 個工作天內召開(太早大家還在善後,太晚就忘記細節了):
# 事件回顧報告
## IR-2026-001:電商平台 Credential Stuffing 攻擊事件
### 事件摘要
- 事件類型:Credential Stuffing(撞庫攻擊)
- 發生時間:2026-02-27 21:30 ~ 2026-02-28 02:00
- 持續時間:約 4.5 小時
- 嚴重等級:P1
- 影響範圍:30 個帳號被入侵,5 筆可疑訂單(總金額 NT$127,000)
### 時間線
(從偵測到復原的完整時間線,略)
### 根本原因
使用者在其他平台使用相同的帳號密碼,該平台資料外洩後,
攻擊者利用外洩的帳密清單對我們的登入 API 進行撞庫攻擊。
我們的系統缺乏:
1. 登入行為異常偵測(同 IP 大量登入嘗試未觸發告警)
2. 強制或鼓勵 MFA
3. 已知外洩密碼的比對機制
### 做得好的地方 ✅
- 監控系統在攻擊開始後 15 分鐘內發出告警
- On-call 工程師在 5 分鐘內回應
- 事件時間線記錄完整
- 客服團隊快速回應客戶詢問
### 需要改進的地方 🔧
- 告警規則的閾值太高,應該更早觸發
- 沒有預先準備好的 Credential Stuffing 應變 Playbook
- 封鎖 IP 的流程需要手動操作 AWS Console,耗時太久
- 客戶通知信的範本沒有事先準備好
### 改善行動項目
| 項目 | 負責人 | 預計完成日 | 優先順序 |
|------|--------|-----------|---------|
| 導入 MFA 並在登入頁面推廣 | 前端組 Alice | 2026-03-15 | P1 |
| 建立自動化 IP 封鎖機制 | 後端組 Bob | 2026-03-10 | P1 |
| 整合 HaveIBeenPwned API 檢查密碼是否外洩 | 後端組 Charlie | 2026-03-20 | P2 |
| 調整登入異常偵測的告警閾值 | SRE Diana | 2026-03-08 | P1 |
| 準備客戶通知信範本 | PM Eve | 2026-03-05 | P2 |
| 撰寫 Credential Stuffing Playbook | 全隊 | 2026-03-31 | P2 |
飛飛觀點:
事後檢討會議的「無咎」原則非常重要。不要問「是誰的錯」,要問「是什麼讓這件事發生了」。如果工程師怕被責備,下次發現異常就不敢回報,那才是最大的損失。
三、建立你的事件處理流程:從零到一的實戰指南
了解了四個階段之後,讓我們來建立一份實際可用的事件回應 SOP。
3.1 事件回應流程圖
┌──────────────┐
│ 偵測到告警 │
│ 或接到通報 │
└──────┬───────┘
│
┌──────▼───────┐
│ 初步評估 │
│ 是否為真實 │
│ 安全事件? │
└──────┬───────┘
│
┌────────┴────────┐
│ │
┌─────▼─────┐ ┌─────▼─────┐
│ 是:分級 │ │ 否:記錄 │
│ 並啟動 │ │ 並關閉 │
│ 回應流程 │ │ │
└─────┬─────┘ └───────────┘
│
┌────────┼────────┐
│ │ │
┌────▼───┐ ┌──▼──┐ ┌──▼────┐
│ P1/P2 │ │ P3 │ │ P4 │
│ 立即 │ │ 4hr │ │ 下個 │
│ 召集 │ │ 內 │ │ 工作日 │
│ 團隊 │ │ 回應 │ │ 處理 │
└────┬───┘ └──┬──┘ └──┬────┘
│ │ │
┌────▼────────▼───────▼────┐
│ 封鎖與止血 │
│ • 隔離受影響系統 │
│ • 封鎖攻擊來源 │
│ • 保存證據 │
└────────────┬─────────────┘
│
┌────────────▼─────────────┐
│ 消除與修復 │
│ • 找到根本原因 │
│ • 清除攻擊者存取 │
│ • 修補弱點 │
└────────────┬─────────────┘
│
┌────────────▼─────────────┐
│ 復原與監控 │
│ • 逐步恢復服務 │
│ • 加強監控 72 小時 │
│ • 通知受影響使用者 │
└────────────┬─────────────┘
│
┌────────────▼─────────────┐
│ 事後活動 │
│ • 撰寫事件報告 │
│ • 召開檢討會議 │
│ • 執行改善項目 │
│ • 法規通報(如需要) │
└──────────────────────────┘
3.2 事件回應 Playbook 模板
Playbook 就像是針對特定類型事件的「標準作業程序」。與其在事件發生時才想該做什麼,不如先為常見的攻擊類型寫好劇本。
以下是一個可以直接使用的 Playbook 模板:
# Playbook:[事件類型名稱]
## 適用情境
- 什麼情況下要啟動這份 Playbook
## 嚴重等級判斷
- P1 條件:...
- P2 條件:...
## 初步確認步驟
1. 檢查 [具體的日誌/監控]
2. 確認 [具體的指標]
3. 判斷 [真實性條件]
## 封鎖措施
### 立即執行(前 15 分鐘)
- [ ] 動作一
- [ ] 動作二
### 短期措施(前 1 小時)
- [ ] 動作一
- [ ] 動作二
## 消除步驟
- [ ] 找出根本原因
- [ ] 清除 [具體項目]
## 復原步驟
- [ ] 驗證修復
- [ ] 恢復服務
- [ ] 加強監控
## 通知清單
- [ ] 內部:[誰]
- [ ] 外部:[誰]
- [ ] 主管機關(如適用)
## 證據保存
- [ ] 需要保存的日誌
- [ ] 需要保存的系統快照
3.3 台灣法規通報要求
在台灣,資安事件發生後可能需要通報主管機關。這不是「做好人」,而是法律義務:
| 法規 | 通報對象 | 通報時限 | 適用情況 |
|---|---|---|---|
| 個人資料保護法(2025 年修正) | 個資保護委員會 + 當事人 | 發現後 72 小時內通報機關;查明後 30 日內通知當事人 | 個資外洩事件 |
| 資通安全管理法 | 主管機關 + 上級機關 | 1 小時內通報(依嚴重等級) | 公務機關與特定非公務機關 |
| 上市櫃公司資通安全管控指引 | 證交所/櫃買中心 | 發生後儘速通報 | 上市櫃公司 |
飛飛觀點:
2025 年個資法修正後,個資外洩的通報義務變得更加嚴格。通報不是「示弱」,拖延通報才是真正的風險——不只有行政裁罰,還可能面臨民事求償。及時通報反而能展現組織的負責態度,降低後續的法律風險。
四、事件回應工具箱:實用的 Node.js 輔助工具
以下是幾個你可以整合進系統中的事件回應輔助工具範例:
4.1 安全事件自動告警
// middleware/securityMonitor.js
// 簡易的安全事件偵測中介軟體
const Redis = require('ioredis');
const redis = new Redis();
const ALERT_THRESHOLDS = {
LOGIN_FAILURE: { count: 10, windowSeconds: 300 }, // 5 分鐘內 10 次登入失敗
API_RATE: { count: 100, windowSeconds: 60 }, // 1 分鐘內 100 次 API 請求
SENSITIVE_ACCESS: { count: 5, windowSeconds: 600 }, // 10 分鐘內 5 次敏感資料存取
};
async function trackSecurityEvent(eventType, identifier) {
const key = <code class="kb-btn">security:${eventType}:${identifier}</code>;
const threshold = ALERT_THRESHOLDS[eventType];
if (!threshold) return;
const count = await redis.incr(key);
if (count === 1) {
await redis.expire(key, threshold.windowSeconds);
}
if (count >= threshold.count) {
await triggerAlert({
type: eventType,
identifier,
count,
window: threshold.windowSeconds,
timestamp: new Date().toISOString(),
});
}
}
async function triggerAlert(alertData) {
console.error('[SECURITY ALERT]', JSON.stringify(alertData));
// 發送到 Slack
await fetch(process.env.SLACK_WEBHOOK_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
text: <code>🚨 安全告警:${alertData.type}\n</code> +
<code>來源:${alertData.identifier}\n</code> +
<code>次數:${alertData.count} 次(${alertData.window} 秒內)\n</code> +
<code class="kb-btn">時間:${alertData.timestamp}</code>,
}),
});
// 記錄到事件追蹤系統
await saveIncidentAlert(alertData);
}
module.exports = { trackSecurityEvent };
4.2 證據保存腳本
事件發生時,第一件事就是保存證據。以下腳本可以快速收集關鍵資訊:
// scripts/collectEvidence.js
// 資安事件證據收集腳本
const fs = require('fs');
const { execSync } = require('child_process');
const path = require('path');
async function collectEvidence(incidentId) {
const evidenceDir = path.join('/secure-evidence', incidentId);
fs.mkdirSync(evidenceDir, { recursive: true });
console.log(<code class="kb-btn">📁 證據收集開始:${incidentId}</code>);
console.log(<code class="kb-btn">📂 儲存目錄:${evidenceDir}</code>);
// 1. 收集系統日誌
console.log('📋 收集系統日誌...');
execSync(<code>journalctl --since "24 hours ago" > ${evidenceDir}/system.log</code>);
// 2. 收集應用程式日誌
console.log('📋 收集應用程式日誌...');
execSync(<code>cp /var/log/app/*.log ${evidenceDir}/</code>);
// 3. 收集網路連線狀態
console.log('🌐 收集網路連線狀態...');
execSync(<code>netstat -tlnp > ${evidenceDir}/network-connections.txt</code>);
execSync(<code>ss -tlnp >> ${evidenceDir}/network-connections.txt</code>);
// 4. 收集執行中的程序
console.log('⚙️ 收集程序清單...');
execSync(<code>ps auxf > ${evidenceDir}/processes.txt</code>);
// 5. 收集最近登入記錄
console.log('👤 收集登入記錄...');
execSync(<code>last -50 > ${evidenceDir}/login-history.txt</code>);
execSync(<code>lastb -50 > ${evidenceDir}/failed-logins.txt 2>/dev/null || true</code>);
// 6. 計算所有證據檔案的 Hash(確保證據完整性)
console.log('🔏 計算證據 Hash...');
const files = fs.readdirSync(evidenceDir);
const hashes = {};
for (const file of files) {
const filePath = path.join(evidenceDir, file);
const hash = execSync(<code class="kb-btn">sha256sum ${filePath}</code>).toString().trim();
hashes[file] = hash.split(' ')[0];
}
fs.writeFileSync(
path.join(evidenceDir, 'evidence-hashes.json'),
JSON.stringify(hashes, null, 2)
);
console.log(<code>\n✅ 證據收集完成,共 ${files.length} 個檔案</code>);
console.log(<code class="kb-btn">📂 存放位置:${evidenceDir}</code>);
return evidenceDir;
}
// 使用方式
// node scripts/collectEvidence.js IR-2026-001
const incidentId = process.argv[2] || <code class="kb-btn">IR-${new Date().getFullYear()}-${Date.now()}</code>;
collectEvidence(incidentId);
五、事件回應 SOP 完整模板
以下是一份可以直接用在你的團隊的事件回應 SOP 模板:
# [公司名稱] 資安事件回應標準作業程序(SOP)
## 版本紀錄
| 版本 | 日期 | 修改人 | 修改內容 |
|------|------|--------|---------|
| 1.0 | YYYY-MM-DD | OOO | 初版制定 |
## 一、目的
定義資安事件的處理流程與責任分工,確保事件發生時能迅速、
有效地回應,將損害降到最低。
## 二、適用範圍
適用於本組織所有資訊系統、網路設備與資料資產相關的資安事件。
## 三、事件回應團隊(CSIRT)
| 角色 | 姓名 | 聯繫方式 | 備援人員 |
|------|------|---------|---------|
| 事件指揮官 | | | |
| 技術負責人 | | | |
| 溝通聯絡人 | | | |
| 法務/合規 | | | |
## 四、事件分級
(參考前文的 P1-P4 分級表)
## 五、處理流程
### 5.1 偵測與通報
- 收到告警或通報後,由 on-call 人員進行初步評估
- 判定為真實事件後,依據分級標準通知對應人員
- 建立事件追蹤單(IR-YYYY-NNN)
### 5.2 封鎖與止血
- 依據對應的 Playbook 執行封鎖措施
- 保存所有相關證據
- 記錄所有操作於事件時間線
### 5.3 消除與修復
- 找出根本原因
- 清除攻擊者存取路徑
- 修補相關弱點
### 5.4 復原
- 在測試環境驗證修復方案
- 逐步恢復服務
- 加強監控至少 72 小時
### 5.5 事後活動
- 事件結束後 3-5 個工作天內召開檢討會議
- 撰寫事件報告
- 追蹤改善項目
## 六、法規通報
- 個資外洩:72 小時內通報個資保護委員會
- 資安事件(受資安法管轄者):依等級 1 小時內通報
## 七、文件附錄
- 附錄 A:Playbook 清單
- 附錄 B:聯絡清單
- 附錄 C:證據收集指引
- 附錄 D:事件報告模板
六、團隊落地的務實建議
第一步:先有,再完善
不要試圖一次寫出完美的 SOP。先寫一份「能用」的版本,可能只有一頁——誰是 on-call、出事打什麼電話、最基本的封鎖步驟。有了這個起點,每次處理完事件後再逐步補充。
第二步:從常見攻擊開始寫 Playbook
不用一次寫完所有攻擊類型的 Playbook。建議從以下五個最常見的開始:
□ Playbook 1:帳號被入侵 / Credential Stuffing
□ Playbook 2:DDoS 攻擊
□ Playbook 3:Web 應用程式弱點被利用(SQL Injection、XSS 等)
□ Playbook 4:惡意軟體 / 勒索軟體感染
□ Playbook 5:個資外洩
第三步:每季做一次桌上演練
演練不需要動到真實系統。把團隊拉到一個會議室(或視訊),丟一個情境,走一遍流程。每次演練後記錄發現的問題,更新 SOP。
第四步:把事件回應整合進 on-call 制度
如果你的團隊有 on-call 輪值,把安全事件的回應也納入。on-call 工程師不需要會處理所有事件,但至少要會做初步評估和分級,然後知道該 call 誰。
七、常見問題 FAQ
Q1:我們是小團隊,只有 5 個人,也需要事件回應 SOP 嗎?
A:尤其需要。大公司可能有專職的資安團隊來處理事件,但小團隊發生資安事件時,影響的就是所有人。一份簡單的 SOP(即使只有一頁)可以在壓力最大的時候,幫你的團隊保持冷靜和有序。從一份簡單的聯絡清單和分級標準開始就好。
Q2:我們沒有 SIEM 或 SOC,怎麼偵測事件?
A:不需要昂貴的工具才能開始。你可以從以下低成本方案開始:
- 應用程式日誌:確保你的 Node.js 應用程式記錄了關鍵的安全事件(登入失敗、權限錯誤等)
- 雲端服務內建告警:AWS CloudWatch、GCP Cloud Monitoring、Azure Monitor 都有免費額度
- 開源工具:Grafana + Loki 做日誌監控、Wazuh 做入侵偵測
- 第三方服務:Uptime Robot(免費版本)監控網站可用性
重點不是工具有多厲害,而是你有沒有在看那些日誌。
Q3:事件發生時,要不要先關閉系統?
A:這取決於事件的性質和嚴重程度,沒有標準答案。一般原則:
- 應該關閉:確認有持續的資料外洩、勒索軟體正在擴散、攻擊者仍在系統中且無法即時阻斷
- 不應輕易關閉:關閉會導致證據消失(記憶體中的攻擊痕跡)、影響範圍可以透過隔離控制、關閉的損失大於事件本身的損失
這個決策應該由事件指揮官根據當下情況判斷,不要由工程師獨自決定。
Q4:怎麼跟客戶溝通資安事件?
A:透明、及時、負責任。以下是溝通的三個原則:
- 說你知道的事實:「我們在某月某日偵測到未授權的系統存取」
- 說你正在做什麼:「我們已經封鎖了攻擊來源,並正在全面調查影響範圍」
- 說使用者應該做什麼:「建議您立即更改密碼,並開啟雙因素認證」
- 不要猜測:還沒查清楚的事情不要亂講,「調查仍在進行中」是完全可以接受的說法
八、結語:最好的事件回應,是讓團隊不再害怕事件
很多團隊害怕資安事件,就像很多人害怕火災。但消防隊員不怕火災,不是因為他們覺得火燒不到自己,而是因為他們知道該怎麼做。
事件回應 SOP 的真正價值,不是那份文件本身,而是準備的過程。當你的團隊一起討論「如果 XXX 發生了怎麼辦」,大家就會開始思考如何預防、如何偵測、如何回應。這個過程本身,就是在強化你的安全文化。
記住 NIST SP 800-61 的核心理念:
「事件回應不是在事件發生時才開始,而是在事件發生之前就已經在進行了。」
從今天開始,花 30 分鐘跟你的團隊坐下來,回答這三個問題:
- 如果我們的系統現在被入侵了,第一個被通知的人是誰?
- 他/她知道接下來該做什麼嗎?
- 我們有沒有一份寫下來的流程可以參考?
如果有任何一個答案是「不知道」或「沒有」,那就是你開始建立事件回應 SOP 的最好時機。
安全不是恐懼,而是創造的基礎。 一份好的事件回應計畫,讓你的團隊在面對資安事件時,從「恐慌」變成「有序處理」——這就是專業。
延伸閱讀
官方資源:
- NIST SP 800-61 Rev.2:Computer Security Incident Handling Guide
- NIST CSF 2.0 — RESPOND & RECOVER 功能
- OWASP Incident Response Cheat Sheet
台灣法規:
系列文章: