我怎麼幫一套診所系統做威脅建模:STRIDE 的 24 個威脅

與其等被攻擊才補洞,不如上線前系統性地問「這裡會怎麼被打」。這篇白話講 STRIDE 威脅建模框架,以及我怎麼用它盤出 ExClinCalc 的 24 個威脅、對應到防護。

#資安#stride#threat-modeling#medical-informatics#教學

重點摘要

大部分人的資安是「出事再補」。威脅建模(threat modeling)反過來 —— 在上線前,有系統地問每個環節「這裡會怎麼被打?」。我用一個叫 STRIDE 的框架,幫診所系統 ExClinCalc 盤出 24 個威脅、逐一對應到防護。這篇講 STRIDE 是什麼、怎麼用,以及它的限制。


為什麼要「事前」想威脅

醫療系統的資料一旦外洩就是不可逆的事件 —— 你沒辦法「收回」已經洩漏的病歷。所以我不想靠「上線後看有沒有出事」,而是在設計階段就把可能的攻擊列清楚

問題是:漫無目的地想「會不會被駭」通常會漏。人腦想威脅容易只想到自己熟悉的那幾種。框架的價值就是給你一份「不會漏掉大類」的檢查表 —— STRIDE 就是這樣一份表。


STRIDE 是什麼

STRIDE 是微軟提出的威脅分類法,把攻擊分成六大類。每個字母是一類:

字母威脅類型白話對應的資安目標
SSpoofing假冒別人的身分登入身分驗證
TTampering偷改資料完整性
RRepudiation做了壞事卻抵賴不可否認性
IInfo Disclosure看到不該看的資料機密性
DDenial of Service讓系統癱瘓可用性
EElevation of Privilege從小權限變大權限授權

用法很簡單:對系統的每個重要環節(登入、每張資料表、每個 API),逐一問這六類威脅「會不會發生?怎麼防?」。六類跑一遍,就不容易漏掉整個大類。


我怎麼套用到 ExClinCalc

ExClinCalc 是一套六角色的診所系統。我對它的每個關鍵環節跑 STRIDE,總共盤出 24 個威脅。挑幾個最有代表性的講:

S(假冒身分)→ 有人偷到密碼冒充醫師

  • 威脅:攻擊者拿到醫師帳密,登入看所有病人。
  • 防護:密碼之外強制 TOTP 雙重驗證。光有密碼進不來,還要手機上那組 6 位數。

T(竄改)→ 有人繞過前端直接改資料庫

  • 威脅:攻擊者不透過我的程式、直接對資料庫下指令改處方。
  • 防護:權限規則寫在資料庫層(RLS),不是只寫在程式。就算繞過前端,資料庫自己還是擋。

R(否認)→ 醫師事後否認開過某張處方

  • 威脅:出事時有人說「不是我做的」,而系統無法證明。
  • 防護:敏感操作(登入、開處方、改病歷)由資料庫 trigger 自動寫入稽核軌跡(audit log),保留 90 天。這道紀錄在資料庫層觸發,應用層竄改不掉。

I(資訊洩漏)→ 金鑰不小心出現在前端

  • 威脅:呼叫外部服務的高權限金鑰被寫進前端程式,任何人打開開發者工具就看到。
  • 防護:金鑰只存在邊緣節點的執行環境秘密裡,永不進前端 bundle、git 歷史、log。

D(阻斷服務)→ 有人狂試密碼把系統打爆

  • 威脅:自動化程式狂送登入請求。
  • 防護:5 次失敗鎖定該帳號 30 分鐘(鎖 user 不鎖 IP —— 攻擊者沒密碼也觸發不了對別人的鎖定)。

E(提權)→ 護理師想拿到醫師的權限

  • 威脅:低權限角色試圖存取高權限功能。
  • 防護:每個角色能看/能做什麼,由 RLS 規則精確界定;沒有一條路徑能讓角色自己升級

這個練習真正的價值

盤完 24 個威脅,最大的收穫不是「列出 24 條」這個數字,而是:

  1. 它逼我對每個環節都想過一遍,而不是只防我本來就會的那幾種。
  2. 它讓防護和威脅一一對得上 —— 我能說清楚「TOTP 是為了擋 S、RLS 是為了擋 T 和 E、audit log 是為了擋 R」,而不是「我加了很多資安功能」這種空話。
  3. 它產生一份可溝通的文件 —— 面試或口試被問「你怎麼確保安全」,我能拿出這張表,而不是臨場硬掰。

誠實說:威脅建模不等於安全

這一段很重要,不能誇大:

  • 威脅建模是「找威脅 + 設計防護」,不是「證明沒有漏洞」。它幫你不漏大類,但想得到的深度取決於做的人。
  • 它不等於滲透測試。我做了多角色帳號互測,但那是功能驗證,不是真人紅隊攻擊。
  • 有些威脅我列了、但目前的防護是「已知但未做」。例如 TOTP 還沒有 backup code 機制(手機遺失的救援),這是我明確標記的待補項,不是假裝不存在。

威脅建模的誠實用法是:它讓我知道自己防了什麼、還沒防什麼 —— 這份清醒本身,比「號稱很安全」有價值得多。


延伸閱讀