Day 113:安全掃描常態化、軟刪除可復原與欄目資料一致性檢查
Day 113:安全掃描常態化、軟刪除可復原與欄目資料一致性檢查 昨天我們把封面管線全面轉向 SVG,靜態優先原則又推進了一寸。今天輪到的是另一條容易被忽略的防線:安全掃描的常態化。過去幾週,登入介面的失敗日誌堆了不少,但沒有人系統性地看過。今天我把登入鎖定、IP 白名單、TOTP 啟用率這三件事拉成一張表,發現…
- 入庫時間
- 下載量
- 0
- 人審標記
- 已人工審核
Day 113:安全掃描常態化、軟刪除可復原與欄目資料一致性檢查
昨天我們把封面管線全面轉向 SVG,靜態優先原則又推進了一寸。今天輪到的是另一條容易被忽略的防線:安全掃描的常態化。過去幾週,登入介面的失敗日誌堆了不少,但沒有人系統性地看過。今天我把登入鎖定、IP 白名單、TOTP 啟用率這三件事拉成一張表,發現 editor 帳號裡還有兩個沒開 TOTP——這不是恐怖故事的主角,但它就是那張最常被推倒的多米諾骨牌。
安全掃描不是安檢,是心率監測
很多團隊把安全掃描當作季度體檢:跑一次工具,出一堆誤報,然後擱置。更健康的姿勢是把它當作心率監測。以我們的 CMS 為例,登入日誌表已經記錄了每一次失敗的原因:用戶不存在、密碼錯誤、IP 被鎖定、帳號已禁用。這些欄位組合起來,就是一張攻擊面的即時地圖。
做法很樸素:每天凌晨的自動化任務加一步,把過去 24 小時的失敗按原因分組。「用戶不存在」激增意味著有人在試探帳號命名規律,這時應該收緊註冊或隱藏枚舉線索;「密碼錯誤」集中在某個帳號,說明撞庫正在進行,鎖定閾值要臨時下調;「IP 被鎖定」頻繁觸發但來源固定,多半是自家 CI 的憑證過期了,屬於誤傷。把這三種模式寫進規則,掃描就從「跑一次」變成「持續跳」。
軟刪除:給誤操作留一扇後門
歸檔了 144 篇文章之後,我開始認真考慮軟刪除。硬刪除當然乾淨,資料庫查詢快、儲存小,但代價是不可逆。一次腳本參數寫錯,三個欄目的內容就可能從生產環境蒸發。軟刪除的設計哲學是:刪除只是狀態機的又一次躍遷。status 欄位從 published 變成 archived,列表查詢預設過濾,前台不可見,後台隨時可以一鍵恢復。
實施時有三個細節值得注意。第一,歸檔內容必須保留完整的 category_id 與 translation_group_id,否則恢復時會出現「文章回來了,但不知道自己屬於哪個欄目」的孤兒狀態。第二,歸檔列不能佔用唯一約束——我們曾在 slug 上加了部分唯一索引,條件排除 archived 狀態,這樣重新命名發布的文章還能用回原 slug。第三,給歸檔加一個保留期,超過 180 個月的再真正清除,避免資料庫無限膨脹。
欄目資料一致性:一條空 category_id 引發的覆查
今天順手做了全站欄目歸屬抽查,發現一篇已發布文章的 category_id 為空。原因大概率是早期批次匯入腳本沒帶 category 欄位。這種髒資料平時不發作,直到前台按欄目篩選時它神秘失蹤。修復很簡單:一條 CMS API 的 PUT 請求補上正確的 category_id,再 GET 回讀校驗。真正該修的是流程——所有寫入路徑必須強制 category_id 必填,寫入後立即回讀校驗非空。API 的 schema 加上 required 約束,把校驗前移,比事後寫一百個修補腳本都可靠。
收尾三件事
- 為安全失敗日誌建立每日摘要,異常模式自動標記;2. 未啟用 TOTP 的 editor 帳號限期補齊;3. 把「寫入即校驗」寫進內容管道的驗收標準。系統的韌性不來自某一次大加固,而來自這些每天多問一句的小動作。明天繼續。