跳至主要內容
>_ITDITD網站資安平台

資安指南

漏洞(CVE)處置實務:徹底修復,並持續監控復發

在中小規模團隊把相依套件的漏洞(CVE)「徹底修復掉」的實務步驟。以掃描→修復→隔離/移交→監控這套『完成的4個定義』為骨架,講解如何用變化偵測避免告警疲勞、不要輕信 HTTP 200、不要讓修復被覆蓋(local→push→deploy)、跨大版本要在與正式環境相同的環境裡建置驗證等現場要點,並結合本站的維運視角加以說明。

發布於 2026-06-11 更新於 2026-06-11 閱讀時間 3 分鐘

對象:人手不多、同時維運多個 Web 應用程式(框架混用),想把相依套件的漏洞(CVE)處置「認真徹底地修一次」的人。這裡不講攻擊手法,只講修好、讓它不會消失、並持續監控為止的實務。容易成為導火線的事故示例,可參考 放任已公開的RCE導致被惡意刷費的經歷

本站的視角:越小的團隊越能靠『兩個機制』守住

人手少的團隊,真正管用的不是花俏的工具,而是兩條紀律。①自動的變化偵測(只對新增的漏洞報警)②local→push→deploy(正式端只接收,不編輯)。本站也是同樣的思路,把相依套件稽核(pnpm audit)放在每次部署前+每日 cron 裡跑,向正式端則只用 push-to-deploy 來分發。不要把它當成一次性的修復事件,而要倒向放好一個會報警的機制並持續運轉的維運方式,這反而是最便宜、最持久的。

先把完成的「4個定義」固定下來

這是為了不讓人隨便說「搞定了」的剎車。先約定好:在這四點齊備之前都算未完成。

① 掃描

用數字掌握現狀

② 修復

根治非dev的嚴重/高危

③ 隔離/移交

修不了·孤立的要明示

④ 監控

加上每日變化偵測

漏洞處置的完成=四點一套。缺一項就會留下『以為修好了』的窟窿。

① 掃描:把現狀變成「數字」

首先,用機器掌握「哪裡有什麼」。手動的不定期檢查一定會中斷。

1

自動探索鎖定檔並掃描

尋找 composer.lock / package-lock.json / pnpm-lock.yaml,每天用 OSS 掃描器(osv-scannerpnpm audit)跑一遍。只是讀鎖定檔,負載極輕。
2

要知道嚴重度不是『一個數字』就能定

同一個漏洞,在 CVSS 裡是高(例如7.5)、但廠商細查後是中,這很常見。CVSS 是機器算出的,容易高估。要決定按哪個基準來劃閾值,並讓團隊所有人都共享『現在用的是哪一個』(→ 什麼是CVSS)。再與是否實際被利用(KEV)相乘,得出優先級。
3

雜訊不是『無視』而是『有依據地排除』

僅用於測試/建置的 dev 相依套件往往不會進入正式打包,多數情況無實害。在掃描器的分組判定裡把 dev 從通知中排除,同時把為什麼排除記進台帳。讓自己處於日後能解釋「這個不是沒修嗎?」的狀態。

② 修復:不要對症療法,要「根治」

止血(對症療法)和根治是兩件不同的工作。兩者都做了才算結束。

只做對症療法(止於圍堵)

  • 用反向代理只擋掉「看起來像那樣」的請求
  • 因為症狀停了就以為「處置完成」
  • 脆弱的相依套件原封不動RCE等仍然存活

根治(正確)

  • 把脆弱的相依套件更新到修復版,堵住窟窿本身
  • 更新後,用記錄確認徵兆是否消失
  • 把止血和根治當作兩件事都做

跨大版本要『在推上正式環境前先建置驗證』

和打修補程式不同,跨大版本(框架14→15、UI工具4→6 等)會伴隨破壞性變更。盲目升級而導致正式建置失敗是最糟的。把改完的原始碼放到與正式環境相同的執行階段(同樣 Node/PHP 版本的容器)裡,等建置/型別檢查完全通過後再 push。失敗的錯誤訊息要一個一個解決(同步→非同步化的 codemod、CSS 的多行 class、型別命名空間被廢棄 等)。若採用舊容器仍在執行的結構,失敗時也能不停機地回切。

把修復的「持久性」也包含進來才算完成

內容哪怕100分,只要下一次部署就被覆蓋,也是0分。這是最容易踩的坑。

1

不要在正式環境的工作樹裡直接commit

在正式環境直接 commit,會與中央儲存庫的歷史分叉,在下一次部署(pull / checkout -f)時被覆蓋,修復就消失了。正式環境是『接收部署結果的地方』,不是用來編輯的地方。
2

務必統一為 local→push→deploy 的單向流動

編輯在本地→commit→push→(正式端)pull/自動部署。即便不得已在正式環境上做了確認性的改動,也務必回退到本地、重新 push(→ 讓正式端只接收的做法)。
3

不要把 HTTP 200 當成『正常』

在共享主機等環境下,即使是致命錯誤也可能回傳 200。驗證務必用實際內容來做——正文裡期望的標題/文字是否被算繪出來(curl | grep)、錯誤記錄裡是否出現新條目、連相依 DB 和帶參數的動態路由都要走一遍。由於快取可能讓生效變慢,要隔一段時間或清快取後再看。

③ 隔離/移交:把修不了的東西「明示」出來

不一定所有問題都能馬上修好。訣竅在於:對修不了的、歸屬他人管轄的、已經不用的,不要含糊其辭

1

孤立·EOL 程式碼要『在刪除前先隔離』

已經不再對外提供的舊原始碼(EOL 框架等),不要直接刪除,而是用重新命名來隔離,並留下寫明「何時·為何隔離·原本的發布位置」的標記。也要把它移出掃描對象。『刪除』不可逆,而『隔離』可以還原、來龍去脈也能留存。
2

先確定確實無人引用,再動手

追查反向代理設定、建置設定、掛載,確認沒有任何地方在引用之後再隔離。掐斷誤被重新發布的事故種子。
3

修不了/他人管轄的要明示移交

自己修不了的,不要放任,而要明示『交給誰·什麼內容』地移交出去。不把未處置變成『看不見的放任』,正是盤點的價值所在。

④ 監控:加上每日「變化偵測」才算完成

走到這一步,最後放上會報警的機制。沒有它,就算辛苦修好了,也察覺不到復發。

不是『把全部每天都報』而是『增加了才報』

把掃描結果與上次取差異(state file)比較,只在出現新增的嚴重/高危時才通知。每天都收到相同內容,很快就會被無視(告警疲勞)。通知彙總成一封郵件(新增·已解決·現狀),用 cron 每日跑。哪怕是共享伺服器,靠一個掃描器二進位檔+cron 也足夠運轉(負載是數毫秒量級·搭配 nice 就更穩妥)。

差異
只通知增加的漏洞=不會疲勞
每日
用 cron 持續運轉
一封
彙總新增·已解決·現狀
到④
加上監控才算完成

盤點時會一併冒出來的「秘密」和「金鑰」

在徹底修復 CVE 的過程中,常常會連相依套件以外的窟窿一起被發現。最有代表性的有兩個——遺忘在公開目錄裡的秘密檔案(webroot 裡放著舊 token,若源自共用範本就所有機器都有同一個窟窿)和交給可能被入侵的暫時環境的 root 金鑰。兩者都是會造成「一處洩漏就全盤皆失」的典型,所以要在和 CVE 處置相同的盤點時機一併檢查(這兩個各自都值得單獨深挖)。秘密的基礎可參考 秘密的安全保管最低限度檢查清單

接下來讀

FAQ

Q漏洞處置做到什麼程度才算『完成』?
A

四點齊備才算完成。①用掃描把現狀變成數字②修復了非dev的嚴重/高危③對修不了的、歸屬他人管轄的、已孤立的程式碼做了明示的隔離/移交④加上了每日變化偵測(能捕捉復發與新增的監控)。尤其在加上④之前都不算完成,因為相依套件明天又可能變得脆弱。

Q每天掃描不會被告警搞得疲憊嗎?
A

『把全部內容每天都報一遍』很快就會被無視。要與上次結果取差異,只在出現新增的嚴重/高危時才通知,這就是『變化偵測』。不每天發送相同內容,反而是最能長期堅持下去的設計。

Q明明修好了,為什麼又退回到脆弱狀態?
A

在正式環境的工作樹裡直接commit,會在下一次部署(pull 或 checkout -f)時被覆蓋,修復就消失了。務必統一為 local→push→deploy 的單向流動,讓正式端『只接收』。修復內容哪怕完美無缺,只要會被覆蓋的維運方式,成果就是零。