[安全需求] 001 SDD 是什麼?讓規格決定安全:從 Specification-Driven Development 看軟體資安新思維

SDD 並不會自動幫你補上資安防護,
但它改變了遊戲規則——因為它讓安全從「規格」那一刻就能被設計、被追蹤、被驗證。


一、程式碼不再是王:從「寫程式」變成「寫規格」

在過去的軟體開發裡,我們總是先寫程式、再回頭寫文件。
結果就是——文件永遠落後,安全永遠被遺忘。

Specification-Driven Development(SDD,規格驅動開發) 正是為了解決這個問題。
它讓規格(specification)成為整個開發的「唯一真實(single source of truth)」。

不再用程式去「解釋規格」,而是讓規格「生成程式」。

在這個模式裡:

  • 規格檔(spec.md)定義功能、使用者故事與安全需求。
  • AI 或生成工具根據規格自動建立架構、測試、與實作任務。
  • 每次修改規格,程式與測試都會重新生成。

也就是說,程式碼變成規格的衍生品。
這種模式不只改變開發流程,也讓安全可以「語言化、結構化、被驗證」。


二、SDD 與資安的交集:安全從此可被設計

傳統的 Secure SDLC(安全軟體開發生命週期)裡,
安全需求常被寫在 Excel、PPT 或 PDF 裡,
上線後大家才發現漏洞一堆。

而在 SDD 裡,安全變成可執行規格(executable spec)
也就是安全需求會直接被寫進系統規格文件中,
並被版本控制、被測試、被生成。

範例:登入系統的安全規格

## 功能:使用者登入系統

### 使用者故事
- 使用者可使用 Email/密碼登入。
- 密碼錯誤超過 5 次,自動鎖帳 15 分鐘。
- 所有請求必須透過 HTTPS。

### 安全需求
- 密碼至少 12 碼,含大小寫與特殊符號。
- 成功登入後簽發 JWT(30 分鐘有效)。
- 登入行為須記錄於 security_log。

這份 spec.md 不只是參考文件,
它可以被工具(如 Speckit、OpenAI、或自建 parser)解析成:

  • 測試腳本(模擬錯誤登入、HTTPS 驗證)
  • API 規約(OpenAPI + JWT requirement)
  • 自動任務(建立 security_log、紀錄登入事件)

    飛飛觀點:
    SDD 不會幫你「想出」防護,但能讓防護成為程式生成的一部分
    從此安全不再被遺忘在文件裡。


三、從文件到契約:安全變成版本化的程式結構

在 SDD 專案中,所有功能都有自己的「規格資料夾」:

specs/005-payment-system/
  ├─ spec.md        # 功能與安全描述  
  ├─ plan.md        # 技術實作計畫  
  ├─ contracts/     # API 合約與權限設定  
  ├─ tests.md       # 自動化測試場景  
  └─ tasks.md       # 產生的開發任務清單  

這樣一來:

  • 資安審查可以直接檢查規格而非代碼。
  • 每次版本更新,安全需求自動隨規格同步。
  • 外部稽核可直接檢視規格版本差異(Diff)。

    技術補充:
    這些規格可用 Git 追蹤差異、用 Markdown Linter 或自訂 Parser 檢查完整性,
    甚至整合 CI/CD pipeline(如 GitHub Actions、GitLab CI)在 Pull Request 時自動跑檢查。


四、技術實作案例:把資安寫進規格

檔案上傳

傳統方式:
開發者寫「可以上傳圖片」。

SDD 實作規格:

## 檔案上傳
- 允許副檔名:.jpg、.png  
- 檔案大小上限:5MB  
- 上傳後即執行 ClamAV 掃描  
- 檔案暫存於 /uploads/tmp  

工具實作:

  • 解析 spec.md 生成 OpenAPI + JSON Schema 驗證邏輯。
  • 自動生成 Python 單元測試(pytest)或 Postman Collection。
  • CI 在部署前跑安全掃描與檔案上傳測試。

表單輸入驗證

## 表單輸入驗證
- 所有輸入需伺服器端驗證。  
- 禁止 HTML 標籤。  
- 特殊字元需 HTML 編碼。  
- 提交後紀錄來源 IP 與 User-Agent。  

實作方式:

  • 規格 → 自動生成驗證模組(使用 Joi / Pydantic)。
  • 自動產生 E2E 測試確認 XSS 防護。

金流 API

## 金流 API
- 所有請求需使用 HMAC 簽章。  
- 交易金額與幣別需雙重驗證。  
- 錯誤訊息不得回傳內部堆疊資訊。  
- 所有交易記錄需附 UUID 供稽核。  

實務應用:
這份規格能直接生成 Swagger API 規約與自動測試;
當規格修改時,CI 會比對前後版本,若刪掉了安全欄位(如 HMAC),
pipeline 會直接 Fail。


五、AI 在 SDD 中的角色:幫你確保一致,而不是代你思考

很多人以為 AI = 自動補漏洞。
但在 SDD 的世界裡,AI 更像是規格守門員(Spec Guardian)

它不會替你設計防護,
但會在規格不完整時發出警告:

[NEEDS CLARIFICATION: 此 API 是否需要 JWT 驗證?]  
[SECURITY WARNING: 新增的 upload API 未定義副檔名白名單]  

這不是「AI 的靈光乍現」,
而是透過三個具體技術步驟實現的。


模板與欄位驗證

在 spec-template.md 裡加上必填欄位:

## 安全需求
- 認證方式(必填):JWT / OAuth / Session  
- 角色權限(必填):Admin / User / Guest  
- Rate Limit(必填):__ 次/分鐘  
- 是否加密敏感資料(必填):Yes / No  

空著不填 → AI 會自動補上 [NEEDS CLARIFICATION]。


靜態分析(Linter)檢查

用 Spectral、Markdownlint 或自訂 Node 腳本掃描 spec.md。

if (/upload/i.test(spec) && !spec.includes('副檔名')) {
  console.error('[SECURITY WARNING] 上傳 API 未定義副檔名白名單');
}
if (!spec.includes('JWT') && /api/i.test(spec)) {
  console.error('[NEEDS CLARIFICATION] API 是否需驗證 Token?');
}

在 PR 或 CI Pipeline 內自動執行,未通過即阻擋合併。


AI 語意檢查(Semantic Audit)

透過 GPT / Claude / Llama-3 實作「語意比對」。

Prompt 範例:

任務:審查以下規格的安全完整性。
請輸出不一致與遺漏的項目,格式如下:
[NEEDS CLARIFICATION: ...]
[SECURITY WARNING: ...]

這樣 AI 就能指出「規格沒定義 JWT」、「錯誤回應洩漏細節」等問題。


飛飛觀點:
AI 不會幫你修安全,但會幫你「看見安全」。
真正的安全文化,是在程式被寫出前就被驗證。


六、資安人員的新角色:從「守門人」到「語言設計師」

傳統角色 SDD 時代角色
撰寫安全政策文件 建立可執行安全規格模板
審查程式碼 審查 spec.md 是否涵蓋必要防護
手動測試漏洞 定義自動化安全測試條件
發現問題 制定安全憲章(Constitution)並交由 CI 驗證

安全人員不再只是稽核,而是與開發者一起「設計安全語言」。


七、組織導入建議

SDD 的精神再好,如果沒有制度支撐、沒有範例可依循,
最終還是會變成一場「文件改革」——寫得漂亮,卻沒人實際用。

導入 SDD 的關鍵不在技術,而在流程與文化的轉變。
以下是我在輔導企業與團隊時最常用的四個落地步驟。


從模板開始:建立團隊的「安全語言」

任何規格驅動開發的第一步,都是統一語言
建議先建立一份通用的 security_spec_template.md,
內容可依公司產品特性擴充,但建議至少包含:

## 安全需求(Security Requirements)
- 認證機制(Authentication):JWT / OAuth2 / API Key
- 權限控制(Authorization):角色矩陣、資源可見性
- 輸入驗證(Input Validation):XSS / SQLi / File Upload Policy
- 敏感資料保護(Data Protection):加密 / Masking / Logging Policy
- 錯誤處理(Error Handling):避免回傳堆疊資訊
- 稽核與追蹤(Audit & Traceability):事件日誌保存期限、審查責任人

建議做法:

  • 用 Git 版本控制這份模板,確保每個專案都使用最新版。
  • 可以參考 [OWASP ASVS Level 2] 作為欄位依據。
  • 讓開發者能直接複製模板開新 feature 目錄,如:
/specs/feature-012-login-system/spec.md

納入 Pull Request 流程:讓規格審查成為開發日常

規格如果沒有綁流程,會被遺忘。
因此第二步是:讓安全規格審查成為 CI Gate。

具體做法如下:

  1. CI 驗證機制:

    • 於 Pull Request(PR)提交時,自動檢查是否附上 spec.md。
    • 若規格未更新或安全欄位為空,PR 自動退回。
    • 可使用 GitHub Actions、GitLab CI 或 Jenkins pipeline 實現。
  2. 規格自動比對(Spec Diff):

    • 每次修改 PR 時,CI 自動比較規格前後版本,
      若發現安全條件被刪除(例如移除了「JWT 認證」),
      則標記 [SECURITY WARNING]。
  3. AI 審查補助:

    • 在 PR 最下方自動附上「AI 規格檢查報告」,列出 [NEEDS CLARIFICATION] 與 [SECURITY WARNING]。

飛飛觀點:
安全不該成為開發流程的「加分題」,而應是「基本題」。
當流程自動提醒、審查可追蹤,團隊自然會習慣「先寫規格、再寫程式」。


規格審查會議(Spec Review):安全與開發共同決策

就像設計審查(Design Review),安全也需要被討論。
規格審查會議 是讓開發、測試、資安在同一張桌上思考「安全邏輯」的時刻。

實施方式:

  • 每週固定一次 30 分鐘「Spec Review」會議。
  • 專案成員輪流展示新功能的 spec.md,重點講安全設計。
  • 資安人員協助檢查規格完整性(如:是否定義權限矩陣、輸入驗證策略)。
  • 會後將共識回寫進規格檔,留下審查紀錄。

這樣做的好處:

  • 開發與安全人員可以在「還沒寫程式前」就釐清風險。
  • 安全決策變得可追蹤、有文件依據。
  • 對外稽核時,可直接出示「安全規格審查紀錄」。

教育與案例庫:讓安全規格成為可複用資產

最後,也是最重要的:
把規格變成知識,而不是一次性文件。

建立一個「安全規格案例庫(Security Spec Library)」,
每次新專案或新功能都能快速複用。

範例可包含:

  • JWT 登入範例:完整的登入/登出流程與 Token 生命週期。
  • 檔案上傳範例:副檔名白名單、大小限制、惡意檔掃描邏輯。
  • SQL Injection 防護範例:ORM Parameter Binding 示範與測試案例。
  • Log Policy 範例:敏感欄位遮蔽、審計日誌格式。

技術補充:

  • 可使用 Git 子模組或私有 npm/pip 套件封裝通用規格。
  • 每季度更新案例庫,納入近期漏洞教訓與新防護範式。
  • 在入職培訓時加入「規格實作演練」,讓新人從 Day 1 就接觸 SDD 思維。

飛飛觀點:
導入 SDD 就像建立一座有紀律的城市。
模板是城市的法規,PR Gate 是交通號誌,教育是公民素養。
當每個開發者都能理解「安全規格=系統的建築藍圖」,
SSDLC 才真正成為日常文化,而不是政策口號。


八、從 Secure Coding 到 Secure Specifying

在 SSDLC by 飛飛,我常說:

「安全不是程式碼寫得多嚴,而是需求一開始就夠清楚。」

過去我們教開發者 Secure Coding;
未來要教的是 Secure Specifying

當安全需求被語言化、模板化、版本化,
安全就不再是「事後檢查」,而是「程式生成的自然結果」。


九、結語:安全不只是文件,而是可執行的真實

SDD 不是魔法,它仍需要人的設計與判斷。
但它讓安全有了新的可能:

把「意圖」轉成「行動」,把「防護」寫進「規格」。

當安全能被設計、被追蹤、被再生,
安全文化就不再只是喊口號——而是每天都在發生。


延伸閱讀

林子婷 (飛飛/Phoebe 菲比)
林子婷 (飛飛/Phoebe 菲比)

講師學歷:臺科資工所、逢甲資工系畢業。
技術專長:OSINT、滲透測試、網站開發、專業易懂教育訓練。
證照書籍:OSCP、OSCE³、著《資安這條路:領航新手的 Web Security 指南》。
教學經驗:60+ 企業教學經驗、指導過上百位學員。
教學特色:新手友善、耐心指導、擅長圖解(流程圖、心智圖)引導學習。
社群經驗:目前經營全臺資安社群 CURA,曾任臺科資安社社長、逢甲黑客社社長。
社群交流:LINE 社群《飛飛的資安大圈圈》,即時分享經驗、鼓勵交流。
社群分享:FB 粉專《資安這條路,飛飛來領路》,分享文章與圖卡整理。
個人網站:feifei.tw 分享資安技術文章;pbtw.tw 分享 AI 相關應用;ssdlc.feifei.tw 分享軟體安全開發流程文章。