7.37 密碼外洩之後:範圍判不出來的時候怎麼定處置
本章幫讀者做兩個決定:外洩之後要讓誰重設密碼,以及要不要通知、通知誰。
它接在 7.30 使用者密碼儲存 之後——那一章決定外洩發生前該把密碼存成什麼樣,這一章處理外洩已經發生之後的動作。
事故當下讀到這裡的話,有兩件事可以在讀完其餘部分之前就先做。發現的時點要記下來,法規時限從這裡起算,不從查明範圍起算。 全部會話要立刻撤銷,它便宜,而做過頭的代價只是使用者重新登入一次。 其餘的判讀都可以排在這兩件事之後。
本章涵蓋與不涵蓋
本章聚焦帳號憑證外洩這一類事件特有的判讀。這件事算不算事故、算哪一級,判準在 8.1 事故分級與啟動條件;止血與回復的通用形態在 8.3 止血與回復策略——那一章給的是可用性訊號驅動的止血節奏(錯誤率、核心成功率、依賴穩定),而憑證外洩沒有那組訊號,止血動作與判停條件由本章給;對外承諾的節奏、狀態頁與補償政策在 8.10 Stakeholder 通訊與外部狀態頁——那三章處理的是所有事故共通的部分,本章只寫憑證這一類與它們不同的地方。一次只影響一個帳號的接管事件走 7.41 單一帳號被接管——那裡的範圍明確而求助者的身分待證,困難的位置與這裡相反。機器憑證與 API key 的撤銷範圍走 7.6 秘密管理與機器憑證治理,判斷依據與這裡不同:那一類的持有者是系統、盤點得出來,重設的代價落在對接方而非使用者。
判讀軸:範圍判不出來的時候怎麼定範圍
多數事故的影響範圍推得出來——哪些請求失敗、哪些租戶受影響、哪一段時間。憑證外洩這一類的預設狀態相反:資料庫被讀走之後,多數系統查不出「哪幾列被讀出去」。成因是列級的存取稽核要另外開功能或裝外掛、預設不開,而開了會顯著增加寫入量;就算開了語句層稽核,留下的也是查詢文字而不是回傳的內容。何況多數外洩走的是備份檔或唯讀副本,那兩條路徑連語句稽核都不經過。走應用層的那一類反而查得出來——請求紀錄留著誰取了什麼。於是範圍判定的預設答案是查不出來——而這一項自己查得到,去看自己的資料庫開了哪一層稽核就知道。
這個決定因此要在不確定之下做,而兩端各有一個失敗形態。範圍抓太小時,漏掉的帳號繼續開著,而攻擊者的使用不產生任何異常訊號——他用的是合法憑證,登入成功、行為正常。範圍抓太大時,處置的代價(使用者流失、客服量、寄信配額)高到讓這個動作被推遲、被打折,最後停在一封建議信上。
兩個失敗形態的共同來源是把問題框成「確定的那些」與「全部」的二選一。實際可行的做法是按證據等級分層,並且把便宜的動作與貴的動作分開施加。
撤銷會話與重設密碼是兩個動作
這兩件事在多數系統裡沒有連動,而把它們當成一件事是外洩處置最常見的漏洞。
**改掉密碼不會讓已經發出的會話失效,除非系統另外做了這件事。**於是常見的形態是:使用者收到通知、改了密碼、認為處理完了,而攻擊者手上那個在外洩之前建立的會話仍然有效,直到它自己過期。
處置的順序因此是先撤銷、再重設。撤銷的能力取決於會話狀態放在哪裡——狀態放在自己查得到的地方時,全面撤銷是一次寫入;無狀態的簽章 token 沒有這個能力,要靠額外維護的撤銷清單,或者等它過期。這條依賴在事件當下補建不起來,取捨要在設計階段決定,見 Session 處理 與 token revocation、session invalidation。
兩個動作的代價差距是分層設計的基礎。撤銷會話便宜——使用者重新登入一次,多數人甚至不會注意到。強制重設貴——使用者要想一個新密碼、可能走進忘記密碼流程、可能就此不再回來。把便宜的那個做滿、貴的那個按證據施加,是這一章處置設計的核心。
三層範圍
分層解的是不確定,不是解代價。範圍查得出來而答案是全體時——確知整份資料被帶走、或存取紀錄重建得出完整清單——正確的處置是全體立即失效,容量問題用分批到期解決,不是用降級處置解決。把明確已握有全部憑證的攻擊者留到使用者下次登入才處理,等於把中間那幾個月送給他。應用層外洩(越權枚舉、被盜的 API key、過度取用的查詢)多半屬於查得出來的那一類,因為請求紀錄重建得出範圍。
剩下的情形才進分層。範圍分三層,各層對應不同的證據強度。
有直接證據被存取的帳號是第一層。證據指的是能指到具體紀錄的線索:攻擊者留下的查詢紀錄、外流樣本裡出現的帳號、已經被拿去登入的帳號。這一層立即失效並強制重設,同時個別通知。
落在攻擊者可及範圍內、而沒有直接證據的帳號是第二層,也是絕大多數帳號的所在。可及範圍指的是同一張表、同一個資料庫執行個體、同一個時間窗內存在的紀錄。這一層的處置是撤銷全部會話,加上「下次登入時強制重設」,而不是立刻讓所有人登入不了。這個組合讓止血在幾分鐘內完成,而把貴的那個動作攤到使用者自然回訪的節奏上。
判定在範圍之外的帳號是第三層。這一層不動,而判定的依據要寫下來——哪一個時間點之後建立的帳號、哪一個分區、哪一套獨立的資料庫。寫得出依據,這一層才算判過;寫不出來的時候它屬於第二層。
第二層還有一個要同時決定的問題:強制重設的期限。這條期限與 7.30 的大帳號庫升級路徑 用的是同一套算法——按回訪分布的分位數定,並把到期日分批錯開,因為期限到期會讓一批人同時湧進重設流程與寄信管道。
通知門檻
通知的判準分兩層,而兩層的決定權不在同一個地方。
法規層由外部規則決定,而它有兩條線、各自有自己的門檻與時鐘。 這兩條在多數討論裡被併成「要不要通報」一個問題,而併起來之後被漏掉的通常是第二條。
第一條是通報監理機關。歐盟的 GDPR 是知悉後 72 小時內;台灣在個資法修正與個人資料保護委員會成立之後方向相同,並以資料類型與筆數設門檻(特種個資、達到一定筆數的個資、以及系統保有筆數達到一定規模者)。
第二條是通知當事人,而它最容易被誤當成產品自己的決定。GDPR 把它訂在另一個條文,門檻是「對當事人的權利與自由構成高風險」,時限寫的是不得無故遲延而非 72 小時;台灣的方向則是達到通報門檻時原則上要在同一個時限內個別通知當事人。兩個法域的門檻與時鐘都不相同,而共同點是這一條帶法定義務,不是自己決定要不要說。
具體的門檻值與辦法仍在調整,判定時要回主管機關的現行規定查,本章寫的是它對工程的要求而非法條本身。
那個要求是這樣的:**時鐘從發現起算,不從查明範圍起算。**這一條與本章的判讀軸直接相咬——範圍多半查不出來,而時限不等它查出來。所以處置要能在範圍未定的狀態下產出一份可提交的通報,把已知與未知分開寫,而不是等調查有結論才動筆。
工程這一端真正要交付的是判定門檻所需的事實:外洩涵蓋哪些欄位、多少筆、時間窗多長、密碼是什麼形態儲存的、有沒有其他欄位屬於特種個資。這些要在事發當下就答得出來,而它們答不答得出來由事前的資料分級與盤點決定,見 7.4 資料保護與遮罩治理 與 data classification。事發之後才開始盤點欄位的團隊,時限會在盤點完成前先到期。
產品層處理的是法定門檻之下的那一段,而它要在事前定。 這一層問的是「還沒到法定門檻、但確實有疑慮時要不要說」,而在事件當下決定它的人會同時承受流失與聲譽的壓力,判斷因此偏向不通知。預先寫下觸發條件(例如第二層範圍涵蓋的帳號數超過某個比例、或涉及的欄位包含什麼)能讓這個決定回到事前,對外承諾的節奏與措辭則走 8.10 Stakeholder 通訊與外部狀態頁。
判讀流程
- 記下發現的時點,法規時限從這裡起算。這一步在混亂的初期最容易漏,而它決定後面每一項的截止時間。
- 立刻撤銷會話。這一步不等範圍判定——它便宜,而且做過頭的代價只是使用者重新登入。
- 分三層定重設範圍,逐層寫下依據。第三層寫不出依據時併回第二層。
- 產出通報所需的事實:欄位、筆數、時間窗、密碼的儲存形態。查不出來的項目要明確標成查不出來,留白會在後續被讀成沒有問題。
- 判定通知門檻,而法規層要分開判兩條——通報監理機關與通知當事人各有自己的門檻與時鐘,漏掉第二條是這一步最常見的失誤。兩條都交給法務與稽核,工程這一端負責供給第 4 步的事實;法定門檻之下的自願通知照事前寫下的觸發條件執行。
- 定第二層的重設期限並分批錯開到期日,算法接 7.30 帳號庫大的時候這兩條路徑怎麼跑。
- 回頭確認密碼的儲存形態撐不撐得住。參數已經落後時,用 7.30 升級路徑 的第二條先打底,它的止血速度不由使用者回訪決定。
這個決定失敗時長什麼樣
最不直觀的形態是範圍抓太大而導致什麼都沒做,因為它的每一步看起來都是負責任的。
它長這樣:團隊發現資料庫可能被讀走,查不出哪些紀錄被存取。有人提出安全的做法是讓全體使用者強制重設,於是去估代價——一個以百萬計的帳號庫、寄信配額不夠、客服量估計是平常的數十倍、負責成長的同事擔心流失。這些顧慮都成立,於是結論變成「先把範圍調查清楚再決定」。調查沒有產出結論,因為日誌本來就不記錄哪幾列被讀出去。幾週之後事情降溫,最後的動作是一封「建議您更改密碼」的信——而只有建議、沒有伴隨強制動作時,重設率由使用者的自發程度決定,那個數字沒有下界。
沒有人發現處置等於零的原因是過程中的每個判斷單獨看都合理:不想過度反應、想先查清楚事實、擔心誤傷使用者。真正的成因在框架——全體重設與精確重設之間沒有中間選項時,代價估算會指向推遲,而推遲的終點是不了了之。分層之所以是這一章的主軸,正是因為它讓「現在就做得到的動作」存在。
常見風險邊界
- 列得出要讓誰重設而指不出會話怎麼撤銷時,處置有一半不會生效,而失效的那一半正是攻擊者當下手上的那一份。
- 事發時答不出「這張表有多少筆、含哪些欄位」時,通報門檻判定不了,而法規時限照常在跑。
- 重設範圍只有「有證據的」與「全部」兩個選項時,實際落地的結果多半是零,形態見「這個決定失敗時長什麼樣」。
- 通知信只寫建議而沒有伴隨強制動作時,重設率由使用者的自發程度決定,而自發率沒有下界——處置的實際覆蓋因此估不出來,也不該當成已經處理過。
- 宣稱「密碼沒有明文外洩」而密碼的儲存參數多年未動時,這句話的實際保護程度未經評估,判讀走 7.30 參數老化的形態與失效。
- 第三層(判定在範圍外)沒有留下依據時,那個判定在事後檢討與稽核中無法複述,而複述不出來的判定會被當成沒有判過。
下一步路由
- 外洩前該把密碼存成什麼樣、參數老化與升級路徑:7.30 使用者密碼儲存
- 會話狀態放哪決定撤銷能力:Session 處理
- 憑證在請求中怎麼帶、以及登入端點的攻擊面:7.36 憑證在請求中怎麼帶
- 機器憑證與 API key 的撤銷範圍:7.6 秘密管理與機器憑證治理
- 欄位分級與盤點(決定事發當下答不答得出來):7.4 資料保護與遮罩治理
- 這件事算不算事故、算哪一級:8.1 事故分級與啟動條件
- 一次只影響一個帳號時的處置與核身:7.41 單一帳號被接管
- 強制重設之後使用者走的那條路徑本身:7.42 密碼重設流程
- 對外承諾的節奏與狀態頁:8.10 Stakeholder 通訊與外部狀態頁