
安全不是最後一關的審查,而是每一步都在做的事。這篇講 SDL 的前半段:需求、設計、開發。測試工具、部署 checklist 和 DevSecOps 自動化放在下一篇。
先講結論
把安全檢查放在開發流程的最後,等於在蓋完房子之後才檢查地基。SDL 的核心是 Shift Left——越早發現問題,修復成本越低,開發者也不會覺得安全團隊是來找碴的。
「事後審查」模式為什麼行不通
傳統的安全流程:
需求 → 設計 → 開發 → 測試 → 部署 → 安全審查
↑
「你這裡有漏洞」
「要改架構」
「上線延後」
你看出問題了嗎?發現問題時已經太晚,修復成本極高。安全團隊變成「壞人」,總是在最後一刻擋住上線。開發者不知道為什麼要改,覺得安全是阻礙。設計層面的安全缺陷到這個階段根本無法修正。
Shift Left 的意思就是:每個階段都融入安全考量,不要集中在最後。
階段一:需求——先想「這功能怎麼被濫用」
在寫任何 code 之前,花 10 分鐘做個最小可行的威脅模型,回答五個問題:
- 這個功能處理什麼敏感資料?(email?信用卡號?)
- 誰會用這個功能?(一般使用者?管理員?)
- 如果被濫用,最壞會怎樣?(資料外洩?金額竄改?)
- 攻擊者最可能從哪裡下手?(API 參數竄改?CSRF?)
- 我們需要什麼防禦?(input validation?權限檢查?)
如果是重要功能,做完整版:畫資料流圖(DFD)→ 在每個信任邊界上套 STRIDE → 評估風險(可能性 x 影響)→ 決定應對策略(避免、緩解、轉移、接受)。
10 分鐘的思考,能省你後面好幾天的返工。
階段二:設計——五個安全設計原則
這五個原則不難記,但很容易忘:
- 最小權限——只給剛好需要的權限。DB 帳號只給 SELECT,不給 DROP
- 縱深防禦——不依賴單一安全措施。WAF + Input Validation + Parameterized Query
- 預設安全——預設狀態就是安全的。新建的 API endpoint 預設需要認證,不是「記得加上認證」
- 失敗安全——出錯時回到安全狀態。Token 驗證失敗 → 拒絕存取,不是允許
- 簡單原則——越簡單越不容易出錯。用成熟的 library,不要自己實作加密
「預設安全」特別值得強調。 如果你的框架需要開發者「記得加上」安全措施才安全,那一定會有人忘記。好的設計是:你什麼都不做,它就是安全的。就像你什麼都不做,deadline 就會自己來一樣。
階段三:開發——安全編碼規範和 Review Checklist
團隊應該有一份安全編碼規範,至少涵蓋這些:
### Input Validation
- 所有外部輸入都必須驗證(type, length, range, format)
- 用白名單(允許什麼)而非黑名單(禁止什麼)
### 資料庫
- 一律 Parameterized Query,禁止字串拼接 SQL
### 認證與授權
- 密碼一律 bcrypt(cost factor >= 12)
- Session token 用 crypto-random
- 每個 API endpoint 都要檢查權限
### 敏感資料
- 禁止在 log 中輸出密碼、token、信用卡號
- .env 和 secrets 不入版控Code Review 時的安全 checklist:
- 有沒有使用者輸入直接進了 SQL / HTML / Shell?
- 新的 API endpoint 有檢查權限嗎?
- 有沒有硬編碼的 secret?
- 錯誤訊息有沒有洩漏內部資訊?
- 有沒有新的 dependency?有已知漏洞嗎?
這份 checklist 不是要讓 review 變慢,而是讓大家養成「看 code 時順便看安全」的習慣。
安全在設計階段修是功能,在開發階段修是 bug,在上線後修是事故。你選哪個?下一篇來看測試工具、部署和 DevSecOps。
延伸閱讀
- 安全開發生命週期(下):測試、部署與 DevSecOps — 本篇的續集
- 資安基礎概念 — 安全思維的基礎
- Web 應用安全實務 — 具體的漏洞與防禦
- Code Review 方法論 — Review 時的安全 checklist