登錄檔是什麼
FlareWatch 歷史上每一類反覆出現的漏洞都被精煉成一項編號的保障措施:一份單段落的規則、其理由,以及指向代碼中強制執行該規則的位置的指針。當出現應該被防止重複出現的漏洞類別或模式時,就會新增保障措施。
該登錄檔是一份工作文件,而非行銷文案。其目的是使團隊——以及團隊所使用的審計優先評審循環——對哪些規則適用於何處保持誠實。該登錄檔從內聯代碼註解引用(例如 // Safeguard 24),使得任何單個文件的讀者都能找到管轄周圍代碼行的規則。
本頁是公開摘要。完整的登錄檔位於源代碼儲存庫中,與其管轄的代碼並存。此處的目的是為安全研究人員、補助金審查者或預期貢獻者提供該登錄檔涵蓋的類別以及其強制執行的紀律類型的概觀。
為什麼需要登錄
保障措施登錄檔只有在防止同一漏洞出現兩次時才能發揮作用。該登錄檔的成功記錄就是答案:
- 每項保障措施都命名了它防止的漏洞。沒有已記憶事件支撐的規則不是保障措施,而是風格偏好。風格偏好應該在 lint 規則中,而不是在登錄檔中。
- 保障措施從代碼中被引用,而不僅從文件中。違反保障措施的代碼更改在評審時會被標記,因為保障措施號在周圍註解中。
- 某些保障措施是自動強制執行的。其中的子集通過 ESLint 規則或在 CI 中執行的 shell 腳本強制執行。其餘的則依賴於作者的紀律加上審計優先評審模式,這在實踐中表現良好。
- 登錄檔由測試保持誠實。多項保障措施由回歸測試固定,這些測試將源文件作為字符串讀取,並斷言反模式不存在。易脆性是該特性的優點:未來的重構若恢復到反模式,測試將在回歸到達生產環境之前失敗。
類別
該登錄檔按領域組織。以下類別是穩定的;隨著發現新的故障模式,會在每個類別中新增特定的保障措施。
| 類別 | 涵蓋範圍 |
|---|---|
| 身份驗證與授權 | 會話驗證的單一檢查點,每條路由上的每個錢包所有權檢查,存取權杖與重新整理權杖之間的跨權杖拒絕,管理員路由閘門。 |
| 資料完整性 | 位址正規化、製作者/消費者邊界處的單位轉換合約、金鑰建構規範,以及禁止將失敗無聲地合併為零值的規則。 |
| 鏈上讀取 | 從智能合約讀取任何值的單一實作規則、從鏈上登錄處進行合約位址解析,以及禁止複製獎勵邏輯的規則。 |
| 顯示正確性 | 集中式數字、貨幣及日期格式化;每個數字顯示上的空值安全性;APR 與 APY 標籤規範;稅率即有效稅率規範。 |
| 警示與通知 | 客戶端與伺服器端警示評估的單一事實來源;明確的允許清單,用於決定哪些警示傳播至已監視錢包;取代規則使「獎勵已到賬」警示取消陳舊的「獎勵可用」警示;跨裝置解除同步。 |
| 持久化與快取 | 規範用於判斷標準儲存是鍵值後端還是 localStorage 的規則;遷移規範;部署範圍的 Service Worker 快取;讀取即時狀態的路由明確動態選擇退出。 |
| UI 與生命週期 | 頁面就緒性閘門、防止暫時性零值取代已知餘額的單調下限,以及冷啟動窗口期間骨架渲染的規則。 |
| 流程與工具 | 明確功能啟動同意的規則、警示表面變更時的完整套件測試執行、伺服器端程式碼中的結構化日誌記錄,以及針對捷徑式修復的審查規範。 |
具代表性規則的幾項
這些是公開安全的防護措施摘要,說明了登記處的性質。它們是重新表述和縮寫的;規範文本位於程式碼旁邊。
鏈上讀取的唯一信息來源
從智能合約讀取的任何值——可領取獎勵、餘額、質押狀態、時期資料、價格——都由服務層中的恰好一個函數計算。每個需要該值的功能都導入相同的函數。如果兩個函數計算相同的值,其中一個是錯誤的;規則是刪除它,而不是添加第三個。
會話驗證的單一瓶頸
FlareWatch 中的每條經過身份驗證的路由都通過單一助手驗證會話 Cookie。沒有路由處理程序獨立驗證會話令牌。這個不變性使服務器端撤銷普遍有效——沒有繞過檢查的後門。
每個錢包的所有權把守,雙方面
每個錢包的路由在服務器端驗證所有權,而不是客戶端。原始審計建立了這條規則,因為之前的工作已關閉了客戶端的把守,但保留了服務器端端點完全無把守。現在兩個部分都作為單獨的明確交付成果被追蹤——在客戶端上關閉,在服務器上關閉——以防止該故障模式再次出現。
使用集中式格式化程序,從不內聯
所有數字、貨幣和日期格式都通過一小組集中式助手進行。沒有組件進行內聯格式化。這條規則與風格無關:當單一區域或貨幣定義發生變化時,應用程序中的每個表面都會隨之更新。表面之間的偏差是無聲的,難以發現,直到用戶注意到。
單位轉換在兩端都有文件記錄
當系統的兩部分交易其單位可能不明確的值時(秒與毫秒、十進制與百分比、小寫與校驗和地址),約定在生產者和消費者兩端都有記錄。只在一端的註解會腐爛;只有在兩端都經過斷言的邊界合約才能在重構中存活。
每個用戶操作一個實現
每個用戶啟動的操作——添加監視的錢包、更改稅率、關閉警報、登出——都恰好有一個實現。這條規則之所以存在,是因為從 UI 的不同部分觸發的操作曾經以微妙的方式偏離:一個入口點會清除快取,另一個則不會,導致一類「操作 X 後的陳舊值」錯誤。
必須明顯的故障模式
某些故障模式本質上是無聲的——誤分類的獎勵、導致通知變為無操作的單位不匹配、永遠不會到達鍵值存儲的關閉記錄。在可能的情況下,登記處要求這些值的生產者大聲宣布其合約,使得未來違反它的更改在測試中失敗,然後再進入生產。
登錄表如何演進
- 新的保障措施。在一類缺陷重複出現或單一缺陷成本足以支持永久規則時新增。
- 已被取代的保障措施。保留在登錄表中並標記為「已被取代」,並指向替代品,以便代碼中的歷史參考保持可解釋性。
- 從工作筆記提升。某些保障措施開始作為交接文件中的非正式規則,一旦被證明具有實質重量就被提升至登錄表。
- 季度審查。臨時 lint 例外和「下季度前完成」標記按季度檢查。已過期的內容要么被解決,要么被明確延期。
為什麼公開發佈
FlareWatch 公開此概述而非完整內部登錄表,原因有二。
- 內部登錄表包含代碼層級的詳細資訊(檔案路徑、鍵值結構名稱、事件時間戳),對團隊和具有代碼存取權限的安全審查員很有幫助,但在沒有該存取權限的情況下不適合發佈。
- 類別和紀律才是真正的故事。評估 FlareWatch 的贈款審查員或安全研究人員想要了解該項目是什麼類型的、它對正確性的重視程度如何、以及其工作迴路是什麼樣的——而不是規則 #91 在哪個檔案中。
希望討論特定保障措施、提議新保障措施或報告缺陷的研究人員歡迎聯繫 [email protected].