[安全需求] 003 SSDLC 安全需求實戰:台灣法規遵循指南:個資法、資安法與產業規範
你的程式碼寫得再安全,如果不符合法規,公司照樣被罰。
法規遵循不是法務的事,而是每一行程式碼的責任。
一、為什麼開發者要懂法規?因為「不知道」不能當藉口
想像你蓋了一棟房子,結構堅固、防盜完善、消防設備齊全。但有一天政府來稽查,發現你的建築執照過期、消防通道寬度不合規、而且沒有無障礙設施——罰單直接開下去,不管你的房子蓋得多漂亮。
軟體開發也是一樣。你可以用 Argon2 加密密碼、做好 CSRF 防護、甚至通過滲透測試零漏洞,但如果你在蒐集使用者資料時沒有取得同意、沒有在隱私政策中告知使用目的、或者在資安事件發生後沒有依法通報——這些都是違法的。
在台灣,跟軟體開發最相關的兩部法律是個人資料保護法(個資法)和資通安全管理法(資安法)。此外,如果你的公司屬於特定產業(如金融業、醫療業),還有更嚴格的產業規範要遵守。
在 SSDLC 的七大階段中,法規遵循屬於第一階段:安全需求定義。因為如果你在需求階段就搞清楚「法律要求我做什麼」,後面的設計、實作、測試就能對齊法規要求,而不是上線後才手忙腳亂地補。
飛飛觀點:
很多開發者覺得法規是法務的事,跟寫程式無關。但事實上,法規裡的每一條要求,最終都會變成一行行的程式碼。你越早理解法規,就越能寫出合規又安全的系統。
二、台灣法規全景圖:開發者該認識的三個層次
在深入個別法規之前,先讓我們用一張全景圖理解台灣的資安與個資法規架構:
| 層次 | 法規 / 規範 | 適用對象 | 主管機關 |
|---|---|---|---|
| 通用法規 | 個人資料保護法(個資法) | 所有蒐集、處理、利用個資的組織 | 個人資料保護委員會(籌備中) |
| 通用法規 | 資通安全管理法(資安法) | 公務機關 + 特定非公務機關 | 數位發展部 |
| 產業規範 | 金融資安行動方案 | 金融業(銀行、保險、證券等) | 金融監督管理委員會(金管會) |
| 產業規範 | 上市櫃公司資通安全管控指引 | 上市櫃公司 | 金管會 / 證交所 / 櫃買中心 |
| 產業規範 | 醫療機構電子病歷製作及管理辦法 | 醫療機構 | 衛生福利部 |
| 國際接軌 | GDPR(歐盟一般資料保護規則) | 處理歐盟居民資料的組織 | 歐盟資料保護機構 |
對開發者來說,個資法和資安法是基本功,產業規範則視你所在的公司而定。
三、個人資料保護法:開發者必知的核心要求
3.1 個資法跟開發者有什麼關係?
個資法規範的是「個人資料的蒐集、處理及利用」。只要你的系統會碰到使用者的個資,你就在個資法的管轄範圍內。
什麼是「個人資料」?根據個資法第 2 條,只要能直接或間接識別特定個人的資料都算,包括但不限於:
| 類別 | 範例 | 開發者常碰到的場景 |
|---|---|---|
| 基本識別資訊 | 姓名、身分證字號、出生年月日 | 會員註冊表單 |
| 聯絡資訊 | Email、手機號碼、地址 | 寄送通知、行銷信件 |
| 財務資訊 | 信用卡號、銀行帳號 | 線上支付功能 |
| 特種個資 | 醫療紀錄、犯罪前科、性生活 | 健康管理 App、背景查核系統 |
| 數位足跡 | IP 位址、Cookie、裝置 ID | 網站分析、廣告追蹤 |
3.2 個資法對開發者的八大要求
以下是從個資法中提煉出,跟軟體開發直接相關的八大要求:
要求一:蒐集前要告知並取得同意
你不能偷偷蒐集使用者資料。系統必須在蒐集前明確告知:蒐集的目的、資料類別、使用期間、對象、地區、方式,以及當事人的權利(如查詢、更正、刪除等)。
// ❌ 不好的做法:註冊時沒有任何告知,直接存資料
app.post('/register', (req, res) => {
db.users.insert(req.body); // 直接存,沒告知
});
// ✅ 好的做法:註冊前展示隱私聲明,取得明確同意
app.post('/register', (req, res) => {
if (!req.body.privacyConsent) {
return res.status(400).json({
error: '請先同意隱私權政策'
});
}
// 記錄同意時間與版本
const user = {
...req.body,
consentTimestamp: new Date().toISOString(),
consentVersion: 'privacy-policy-v2.1',
consentIP: req.ip
};
db.users.insert(user);
});
要求二:不能超出蒐集目的使用
你蒐集 Email 是為了寄訂單通知,就不能拿來發行銷信——除非使用者另外同意。
// ❌ 不好的做法:用訂單通知的 Email 名單直接發促銷
await sendEmail(user.email, '限時優惠!全館 5 折');
// ✅ 好的做法:檢查使用者是否有同意行銷用途
if (user.marketingConsent) {
await sendEmail(user.email, '限時優惠!全館 5 折');
}
要求三:當事人有權查詢、更正、刪除自己的資料
系統必須提供機制讓使用者可以查詢自己被蒐集了哪些資料、要求更正錯誤、甚至要求刪除。
// API 設計應包含這些端點
// GET /api/me/data → 查詢個人資料
// PATCH /api/me/data → 更正個人資料
// DELETE /api/me/data → 刪除個人資料(帳號刪除)
// GET /api/me/data/export → 匯出個人資料副本
要求四:要制定「個人資料檔案安全維護計畫」
非公務機關(也就是一般公司)必須制定安全維護計畫,包含:管理措施、技術措施、認知宣導訓練,以及事故應變機制。
要求五:資安事件發生後要通知當事人
如果發生個資外洩,你必須在查明後通知當事人,告知外洩的事實、個資類別、應變措施等。
要求六:特種個資需要特別處理
醫療、基因、性生活、健康檢查、犯罪前科等「特種個資」,原則上不得蒐集、處理或利用,除非符合法定例外情形(如法律明文規定、當事人書面同意等)。
要求七:委外處理個資要監督受託者
如果你把資料處理委外(例如用第三方雲端服務、委託行銷公司發信),委託方仍然要負監督責任。
要求八:跨境傳輸有限制
個資傳輸到台灣境外時,需要確保接收方的個資保護水準足夠。
3.3 2025-2026 年個資法重大修正:開發者需注意的變化
2025 年 11 月 11 日,總統公布了個資法修正案(施行日期由行政院另定)。這次修正是個資法自施行以來最大規模的修正,由個資會籌備處採「兩階段」推動修法。以下是對開發者的重要影響:
| 修正重點 | 對開發者的影響 |
|---|---|
| 成立「個人資料保護委員會」作為獨立監管機關 | 未來有專責機關統一監管,稽查力度預期增強 |
| 明訂個資事故通報義務 | 發生個資外洩時,須向個資會通報,系統必須有事故偵測與通報機制 |
| 公務機關須設置「個人資料保護長」 | 政府專案開發需配合資料保護長的要求(目前尚未要求民間企業設置) |
| 事故發生後須即時通知當事人 | 企業不得以「尚未查明」為由遲誤通知,系統需預備當事人通知機制 |
| 個資會可逕行處罰,毋庸先令限期改正 | 違規風險大幅提高,不再有「先被警告再改」的緩衝空間 |
目前進度(截至 2026 年 2 月):
值得注意的是,個資保護委員會的正式成立,仍須等待「個人資料保護委員會組織法」完成立法程序。目前組織法草案已在立法院「司法及法制委員會」初審完竣,尚待院會完成三讀。行政院將配合組織法的立法進度,再行指定個資法新法的施行日期。
此外,個資會籌備處已在 2026 年初預告多項子法草案,包括「個人資料檔案安全維護管理辦法」、事故通報相關辦法、檢查非公務機關落實個資法情形作業辦法等,正在公開徵求意見階段。這些子法一旦定案,將直接影響你的系統需要符合的具體技術規格。
飛飛觀點:
個資保護委員會的成立,代表台灣的個資保護即將進入新時代。雖然組織法尚在立法程序中,但子法草案已經在預告了——這代表一切都在加速推進。對開發者來說,現在就把合規做好,遠比之後被罰再來改要划算得多。
四、資通安全管理法:你的公司在管轄範圍嗎?
4.1 資安法是什麼?
如果說個資法保護的是「個人的資料」,那資安法保護的就是「國家的資通安全」。資安法在 2019 年正式施行,2025 年 9 月 24 日公布了施行以來首次重大修正(施行日期由行政院另定)。
資安法管的是兩類對象:
第一類:公務機關
各級政府機關。如果你的公司承接政府專案,雖然你不是公務機關,但你的系統需要符合機關的資安要求。
第二類:特定非公務機關
這包括三種:
| 特定非公務機關類型 | 範例 |
|---|---|
| 關鍵基礎設施提供者 | 電力、電信、交通、金融、醫療等關鍵服務的營運者 |
| 公營事業 | 台電、中華郵政等 |
| 特定財團法人或政府捐助的機構 | 政府持有一定比例的財團法人 |
4.2 資安法對開發者的重點要求
要求一:建立資通安全維護計畫
受規範的機關與組織必須制定資安維護計畫,包含資通系統的安全管理、防護、稽核及事件應變等。
要求二:事件通報義務
發生資安事件時,必須在規定時間內向主管機關通報。
| 事件等級 | 通報時限 | 範例 |
|---|---|---|
| 第一級(輕微) | 72 小時內 | 非核心系統異常 |
| 第二級(一般) | 36 小時內 | 核心系統效能降低 |
| 第三級(重大) | 24 小時內 | 核心系統服務中斷 |
| 第四級(嚴重) | 1 小時內 | 機密資料大量外洩 |
開發者的責任:系統必須有完善的日誌記錄、異常偵測與告警機制,才能在事件發生時快速判斷等級並通報。
要求三:資通系統分級與防護基準
依據系統處理資料的機密性、完整性及可用性,系統被分為不同安全等級,每個等級有對應的防護基準。
資通系統防護基準等級:
普級 → 基本防護(輸入驗證、存取控制、日誌記錄)
中級 → 強化防護(加密傳輸、弱點掃描、定期稽核)
高級 → 最高防護(滲透測試、多因素認證、即時監控)
要求四:委外管理
修正後的資安法明確要求,機關委外辦理資通安全業務時,應與受託者簽訂書面契約,載明權利義務及違約責任。如果你是政府專案的受託廠商,這一點格外重要。
要求五:禁止使用危害國家資通安全產品
2025 年修正將「禁用危害國安產品」提升至法律位階。公務機關不得使用被認定為危害國家資通安全的產品(如特定國家製造的設備或軟體)。
4.3 2025-2026 年資安法修正重點
資安法自 2019 年施行以來,本次(2025 年 8 月 29 日三讀、9 月 24 日公布)是首次重大修正。資安署將在公布後六個月內完成 8 項子法修訂,預計 2026 年上半年與母法同步施行。
| 修正重點 | 說明 |
|---|---|
| 主管機關變更 | 由行政院改為數位發展部,資安業務由資安署執行 |
| 擴大稽核範圍 | 總統府及五院均納入稽核範圍 |
| 禁用危害國安產品 | 公務機關不得下載、安裝或使用危害國家資通安全產品(提升至法律位階) |
| 特定非公務機關須設資安長與專職人員 | 比照公務機關要求,確保資安防護量能 |
| 提高罰則 | 未通報資安事件罰鍰上限提高至 NT$1,000 萬;未改正罰鍰上限提高至 NT$500 萬 |
| 強化稽查權限 | 主管機關可要求到場說明、提出第三方報告或派員檢查 |
| 委外管理法制化 | 委外辦理資安業務須簽訂書面契約,載明權利義務及違約責任 |
| 資安人員適任性查核 | 專職資安人員須進行適任性查核,未通過者不得處理涉及國家機密之業務 |
| 資安演練 | 明確要求機關配合數位發展部辦理資安演練 |
飛飛觀點:
即使你的公司不是資安法的直接管轄對象,但如果你承接政府專案、為關鍵基礎設施提供軟體服務,或者是上市櫃公司的供應商,資安法的要求都會間接影響到你。了解它,是保護自己也保護客戶。
五、產業規範:金融業與上市櫃公司的特別要求
除了通用的個資法和資安法,特定產業還有更嚴格的要求。以下是兩個對軟體開發影響最大的產業規範:
5.1 金融業:金融資安行動方案
金管會在 2020 年發布「金融資安行動方案」,2022 年推出 2.0 版,對金融機構的資安防護提出全面要求。
對開發者的關鍵要求:
| 要求 | 開發實務 |
|---|---|
| 核心系統上線前須做安全測試 | 導入 SAST、DAST、滲透測試 |
| 定期弱點掃描與修補 | 建立持續性的弱點管理流程 |
| 電子交易安全 | 實作多因素認證、交易簽章、防MITM |
| 資安事件通報(30 分鐘 ~ 24 小時) | 完善的日誌與即時告警機制 |
| 導入 ISO 27001 等國際標準 | 系統開發需符合 ISMS 要求 |
5.2 上市櫃公司:資通安全管控指引
金管會要求所有上市櫃公司依照規模分三級,逐步設置資安長、資安專責單位與人員:
| 級別 | 條件 | 要求 |
|---|---|---|
| 第一級 | 資本額 ≥ NT$100 億或台灣 50 成分股 | 資安長 + 資安專責單位 + 主管 + ≥ 2 名專責人員 |
| 第二級 | 其餘未連續虧損的上市櫃公司 | 資安專責主管 + ≥ 1 名專責人員 |
| 第三級 | 連續虧損或每股淨值低於面額 | 鼓勵設置 ≥ 1 名資安專責人員 |
資通安全管控指引同時對開發面提出要求:
✅ 系統開發需求規格須納入資安要求
✅ 用戶輸入輸出須有檢查過濾機制
✅ 上線前須執行原始碼掃描
✅ 定期辦理弱點掃描與滲透測試
✅ 委外開發須於合約載明資安要求與稽核權
六、實戰案例:台灣電商平台的法規遵循需求
讓我們用一個完整的案例,把前面的法規知識串起來。
場景
你的團隊正在為一家台灣電商平台開發新版會員系統。這個系統會處理:會員註冊、登入、訂單管理、信用卡支付、行銷推播、退貨退款。公司是上市公司(第二級)。
法規遵循需求分析
Step 1:盤點會碰到的個資
| 資料類別 | 具體內容 | 蒐集目的 | 法規依據 |
|---|---|---|---|
| 基本身分 | 姓名、Email、手機 | 會員管理、訂單通知 | 個資法 §19 |
| 財務資料 | 信用卡號、銀行帳號 | 支付處理 | 個資法 §19 + PCI DSS |
| 交易紀錄 | 訂單內容、金額、時間 | 訂單管理、退貨退款 | 個資法 §19 |
| 行銷相關 | 瀏覽紀錄、偏好標籤 | 個人化推薦 | 個資法 §19(需另取同意) |
| 日誌資料 | IP 位址、裝置資訊 | 資安監控、異常偵測 | 資安法 + 個資法 |
Step 2:轉化為安全需求規格
## 會員系統安全需求規格(法規遵循)
### 1. 個資蒐集告知與同意(個資法 §8)
- 註冊頁面須顯示隱私權政策全文
- 使用者須勾選同意後才能完成註冊
- 系統記錄同意時間、IP、政策版本
- 行銷用途須獨立取得同意(不得與服務同意綁定)
### 2. 當事人權利行使機制(個資法 §3)
- 提供「個人資料查詢」功能
- 提供「個人資料更正」功能
- 提供「帳號刪除」功能(含關聯資料清除)
- 提供「個人資料匯出」功能
- 處理期限:收到請求後 15 日內回覆
### 3. 資料安全保護(個資法 §27 + 資安管控指引)
- 信用卡號以 AES-256 加密存儲
- 密碼以 Argon2id 雜湊後存儲
- 所有 API 傳輸使用 TLS 1.2 以上
- 信用卡顯示時遮蔽為 **** **** **** 1234
### 4. 日誌與稽核(資安法 + 管控指引)
- 記錄所有登入、權限變更、資料存取行為
- 日誌中不得包含完整信用卡號或密碼
- 日誌保存至少 6 個月
- 異常行為即時告警
### 5. 資安事件通報準備(資安法 + 個資法)
- 建立資安事件分級與通報流程
- 系統具備事件偵測與告警能力
- 預備當事人通知機制(Email + 站內信)
Step 3:轉化為安全驗收標準
# SAC-LC-01:個資蒐集同意驗證
Scenario: 未同意隱私政策不得完成註冊
Given 使用者在註冊頁面填寫完資料
When 使用者未勾選「同意隱私權政策」就點擊註冊
Then 系統應顯示錯誤訊息「請先同意隱私權政策」
And 不得將任何資料寫入資料庫
# SAC-LC-02:行銷同意獨立取得
Scenario: 行銷同意與服務同意分離
Given 使用者在註冊頁面
When 使用者同意服務條款但未勾選行銷同意
Then 使用者可以成功完成註冊
And 資料庫中 marketing_consent 欄位為 false
And 系統不得對該使用者發送行銷訊息
# SAC-LC-03:當事人資料刪除權
Scenario: 使用者要求刪除帳號
Given 使用者已登入並進入帳號管理頁面
When 使用者點擊「刪除帳號」並確認
Then 系統應在 15 個工作日內完成以下操作:
- 刪除個人識別資訊(姓名、Email、手機)
- 交易紀錄去識別化(保留帳務記錄但移除個資)
- 撤銷所有有效的 JWT 與 Session
- 發送確認信至使用者 Email
# SAC-LC-04:信用卡資料保護
Scenario: 信用卡號不得以明碼存儲
Given 系統資料庫中存有信用卡資訊
When 直接查詢資料庫的信用卡欄位
Then 應只能看到加密後的密文
And API 回傳的信用卡資訊必須遮蔽為 **** **** **** 末四碼
# SAC-LC-05:日誌不得記錄敏感資料
Scenario: 日誌中不包含信用卡號與密碼
Given 使用者進行登入或支付操作
When 系統記錄操作日誌
Then 日誌中不得包含完整信用卡號
And 日誌中不得包含使用者密碼(含雜湊值)
And 日誌中手機號碼須遮蔽為 09XX-XXX-567
七、法規遵循 Checklist:開發者可以直接用的檢核清單
以下是一份可以直接用於專案的法規遵循檢核清單:
個資法遵循 Checklist
## 蒐集階段
- [ ] 隱私權政策已撰寫並放置於系統可見位置
- [ ] 註冊 / 蒐集流程中有明確的告知與同意機制
- [ ] 行銷用途的同意與服務同意分開取得
- [ ] 同意紀錄(時間、版本、IP)已儲存
## 處理與利用階段
- [ ] 個資使用未超出告知的蒐集目的
- [ ] 特種個資有額外的保護與同意機制
- [ ] 資料存取有權限控制(最小權限原則)
- [ ] 敏感資料已加密存儲
## 當事人權利
- [ ] 提供個資查詢功能
- [ ] 提供個資更正功能
- [ ] 提供帳號 / 個資刪除功能
- [ ] 提供個資匯出功能
- [ ] 權利行使的回覆時限在 15 日內
## 安全維護
- [ ] 已制定個人資料檔案安全維護計畫
- [ ] 傳輸使用 TLS 1.2+
- [ ] 密碼以安全雜湊演算法存儲
- [ ] 有完善的存取日誌機制
- [ ] 日誌中未記錄敏感個資明碼
## 事件應變
- [ ] 有個資外洩通知流程
- [ ] 有事件分級與通報機制
- [ ] 定期演練事件應變流程
資安法遵循 Checklist(適用於承接公務機關專案或特定非公務機關)
## 系統開發階段
- [ ] 開發需求規格已納入資安要求
- [ ] 使用者輸入已做驗證與過濾
- [ ] 上線前已執行原始碼掃描(SAST)
- [ ] 上線前已執行弱點掃描(DAST)
- [ ] 未使用被列為「危害國安」的產品或套件
## 系統運維階段
- [ ] 已建立資安事件分級與通報流程
- [ ] 日誌保存符合規定期限
- [ ] 定期辦理弱點掃描與修補
- [ ] 委外廠商合約載明資安要求
## 人員與組織
- [ ] 已設置資安專責人員(依級別)
- [ ] 資安人員有定期教育訓練
- [ ] 全員完成資安意識宣導
八、團隊落地建議:讓法規遵循變成開發日常
建議一:在 Spec Review 中加入「法規檢查點」
如果你已經在做 SDD(規格驅動開發),在 spec.md 的模板中加入一個「法規遵循」區塊:
## 法規遵循(Legal Compliance)
### 涉及的個資類別
- [ ] 基本識別資訊
- [ ] 聯絡資訊
- [ ] 財務資訊
- [ ] 特種個資
- [ ] 其他:___
### 個資法要求
- [ ] 已確認蒐集目的與告知方式
- [ ] 已確認同意取得機制
- [ ] 已確認當事人權利行使機制
### 產業規範
- [ ] 不適用
- [ ] 金融業規範
- [ ] 上市櫃資安管控指引
- [ ] 其他:___
建議二:建立「法規需求對照表」
每個專案開始時,花 30 分鐘做一份法規需求對照表,把法規要求對應到具體的技術實作:
| 法規要求 | 技術實作 | 負責人 | 完成狀態 |
|---|---|---|---|
| 個資法 §8 告知義務 | 隱私政策頁面 + 同意 Checkbox | 前端工程師 | ⬜ |
| 個資法 §27 安全維護 | AES-256 加密 + Argon2 雜湊 | 後端工程師 | ⬜ |
| 資安管控指引 – 原始碼掃描 | CI/CD 整合 SonarQube | DevOps | ⬜ |
建議三:把法規測試納入 CI/CD
某些法規要求可以自動化驗證:
// 範例:自動化測試確認 API 回應不洩漏敏感資料
describe('法規遵循 - 個資保護', () => {
it('API 回應中信用卡號應被遮蔽', async () => {
const res = await request(app)
.get('/api/me/payment-methods')
.set('Authorization', <code class="kb-btn">Bearer ${token}</code>);
res.body.cards.forEach(card => {
// 信用卡號應被遮蔽,只顯示末四碼
expect(card.number).toMatch(/^\*{4}\s\*{4}\s\*{4}\s\d{4}$/);
});
});
it('日誌中不應包含密碼', async () => {
await request(app)
.post('/api/auth/login')
.send({ email: 'test@test.com', password: 'MyP@ssw0rd123' });
const logs = await getRecentLogs();
logs.forEach(log => {
expect(log.message).not.toContain('MyP@ssw0rd123');
});
});
});
建議四:每季做一次法規更新同步
台灣的資安與個資法規正在快速演進(2025 年就有個資法和資安法的重大修正)。建議每季花一個小時,掃一下法規動態,確認你的系統是否需要調整。
九、常見問題 FAQ
Q1:我們是小公司,個資法也管得到嗎?
A:是的。個資法適用於所有蒐集、處理、利用個人資料的組織,不論規模大小。只要你的系統有使用者註冊、存了使用者的 Email 或手機號碼,就在管轄範圍內。差別在於,個資保護委員會未來可能會依組織規模制定不同程度的管理要求。
Q2:我們不是政府單位也不是關鍵基礎設施,資安法跟我無關?
A:直接管轄可能無關,但如果你承接政府專案、是上市櫃公司、或者你的客戶是受管轄的機關,資安法的要求會間接影響你。而且,上市櫃公司的「資通安全管控指引」對所有上市櫃公司都有約束力。
Q3:個資法和 GDPR 有什麼差異?如果同時要遵守兩者怎麼辦?
A:主要差異在於:GDPR 有更明確的「被遺忘權」與「資料可攜權」、更嚴格的跨境傳輸規定、以及更高的罰鍰上限(最高全球營業額 4%)。如果你的系統同時處理台灣與歐盟使用者的資料,建議以較嚴格的 GDPR 為基準設計,這樣同時能滿足個資法的要求。
Q4:違反個資法最嚴重會怎樣?
A:民事方面,依據個資法第 28 條,同一事件被害人的損害賠償總額最高 NT$2 億元(所涉利益超過 2 億元者,以該所涉利益為限),且支持團體訴訟。刑事方面,意圖營利的違法行為最重可處 5 年以下有期徒刑,併科 NT$100 萬以下罰金,且為非告訴乃論。2025 年修正後新增了個資事故通報義務,未依規定通報個資會將直接面臨行政裁罰,且個資會可毋庸先令限期改正即逕行處罰——這代表不再有「被警告一次再改」的緩衝空間。
📌 法條參考:個資法第 28 條(第四章 損害賠償及團體訴訟)
公務機關違反本法規定,致個人資料遭不法蒐集、處理、利用或其他侵害當事人權利者,負損害賠償責任。但損害因天災、事變或其他不可抗力所致者,不在此限。
被害人雖非財產上之損害,亦得請求賠償相當之金額;其名譽被侵害者,並得請求為回復名譽之適當處分。
依前二項情形,如被害人不易或不能證明其實際損害額時,得請求法院依侵害情節,以每人每一事件新臺幣五百元以上二萬元以下計算。
對於同一原因事實造成多數當事人權利受侵害之事件,經當事人請求損害賠償者,其合計最高總額以新臺幣二億元為限。但因該原因事實所涉利益超過新臺幣二億元者,以該所涉利益為限。
同一原因事實造成之損害總額逾前項金額時,被害人所受賠償金額,不受第三項所定每人每一事件最低賠償金額新臺幣五百元之限制。
第二項請求權,不得讓與或繼承。但以金額賠償之請求權已依契約承諾或已起訴者,不在此限。
十、結語:法規不是枷鎖,是信任的基石
回到 SSDLC 的核心理念——安全不是恐懼,而是創造的基礎。法規遵循也是一樣。
個資法不是來找你麻煩的,它是告訴你:使用者信任你保管他們的資料,你有責任好好保護。資安法也不是製造官僚,它是在說:當整個社會越來越依賴數位系統,你的系統安全就是公共安全的一部分。
法規合規不需要一步到位。就像蓋房子要先拿到建照才能動工,你也可以:
- 先了解:花一個下午讀完這篇文章,搞清楚你的系統碰到哪些法規
- 再盤點:用 Checklist 檢查目前的合規狀態
- 逐步補齊:從風險最高的地方開始,一個一個修
當你的系統不只技術上安全,法規上也合規,你就在告訴使用者和客戶:「我值得你信賴。」
這份信任,是任何技術都買不到的競爭力。
延伸閱讀
台灣法規原文:
主管機關資源:
系列文章:
國際參考:
[安全需求] 002 如何撰寫安全需求規格書?從使用者故事到安全驗收標準:Abuse Case 實戰教學
你不需要成為資安專家才能寫好安全需求。
你只需要學會一件事——在寫「使用者可以做什麼」的同時,問自己「攻擊者會怎麼做」。
一、安全需求規格書是什麼?為什麼你應該在乎?
想像你委託建築師蓋一棟房子。你跟他說:「我要三房兩廳、採光好、有車庫。」建築師照做了,房子蓋得漂亮,但你搬進去才發現——大門沒有鎖、窗戶沒有裝柵欄、後門直接通向公共巷弄。
你會說:「可是我沒有要求裝鎖啊!」
問題就在這裡。你沒有說,所以他沒有做。
軟體開發也是一樣。當你只寫了功能需求(使用者可以登入、可以下單、可以上傳檔案),卻沒有寫安全需求(密碼要怎麼存、誰可以看到訂單、上傳的檔案要不要掃毒),那就等於蓋了一棟沒有門鎖的房子。
安全需求規格書就是在功能需求旁邊,明確寫出「這個功能的安全防線在哪裡」的文件。它不是另一份獨立文件,而是跟功能需求共生共長的安全說明。
在 SSDLC 的七大階段中,安全需求定義是第一階段,也是影響最深遠的階段。根據 IBM 的研究,在需求階段修復一個安全缺陷的成本,只有上線後才修復的 1/30 到 1/100。換句話說,你現在花一小時寫安全需求,可以幫未來的你省下一百小時的修補地獄。
二、傳統需求 vs. 安全需求:差在哪裡?
很多開發者會說:「我有寫需求啊!」但讓我們來看看傳統需求和加入安全考量的需求有什麼不同:
範例:會員登入功能
傳統功能需求:
使用者可以用 Email 和密碼登入系統。
忘記密碼時,可以透過 Email 重設密碼。
看起來沒問題對吧?但如果你是攻擊者,你會怎麼想?
攻擊者的內心獨白:
「密碼有長度限制嗎?我來暴力破解看看。」
「錯誤幾次會鎖帳號嗎?沒有的話我可以一直試。」
「重設密碼的連結會過期嗎?不會的話我撿到舊連結就能用。」
「登入失敗會跟我說是帳號錯還是密碼錯嗎?這樣我可以先確認帳號存不存在。」
加入安全需求後的規格:
使用者可以用 Email 和密碼登入系統。
安全需求:
- 密碼至少 12 碼,需包含大小寫英文、數字與特殊符號。
- 密碼以 Argon2id 雜湊後存入資料庫,禁止明碼儲存。
- 連續登入失敗 5 次,帳號鎖定 15 分鐘。
- 登入失敗訊息統一為「帳號或密碼錯誤」,不得透露哪一項有誤。
- 成功登入後簽發 JWT,有效期限 30 分鐘,Refresh Token 7 天。
- 所有登入行為(成功與失敗)須記錄於 security_log,包含 IP 與 User-Agent。
- 重設密碼連結 30 分鐘後失效,且僅能使用一次。
- 重設密碼後,所有已簽發的 JWT 與 Session 必須失效。
看到差別了嗎?安全需求不是另一份文件,而是功能需求的安全標注。
三、從使用者故事到 Abuse Case:學會用攻擊者的腦袋思考
3.1 使用者故事(User Story):正常人怎麼用
使用者故事是敏捷開發中最常見的需求表達方式:
作為一個(角色),我想要(功能),以便(價值)。
例如:
作為一個買家,我想要上傳商品照片,以便賣家能看到我要退貨的商品狀況。
這描述了正常使用者的行為。但在 SSDLC 裡,我們需要多問一個問題:
「如果使用者不正常呢?」
3.2 Abuse Case(濫用案例):壞人怎麼玩
Abuse Case 是使用者故事的邪惡雙胞胎。它的格式是:
作為一個(攻擊者角色),我想要(攻擊行為),以便(惡意目的)。
讓我們用上面的退貨照片功能來示範:
| 使用者故事(正常) | Abuse Case(攻擊) |
|---|---|
| 作為買家,我想上傳商品照片 | 作為攻擊者,我想上傳一個偽裝成 .jpg 的 PHP 後門程式 |
| 作為買家,我想上傳多張照片 | 作為攻擊者,我想上傳 1000 張超大檔案,癱瘓伺服器 |
| 作為買家,我想在退貨說明中輸入文字 | 作為攻擊者,我想在說明欄注入 <code><script></code> 竊取賣家 Cookie |
| 作為買家,我想查看自己的退貨紀錄 | 作為攻擊者,我想修改 URL 中的 ID 查看別人的退貨紀錄 |
這就是 Abuse Case 的威力——它逼你站在攻擊者的角度,思考每一個功能可能被如何濫用。
3.3 實戰演練:為常見功能寫 Abuse Case
讓我們用台灣常見的應用場景來練習:
功能:線上轉帳
| 正常使用者故事 | Abuse Case |
|---|---|
| 作為用戶,我想轉帳給朋友 | 作為攻擊者,我想竄改轉帳金額或收款帳號(MITM) |
| 作為用戶,我想查看轉帳明細 | 作為攻擊者,我想透過 IDOR 查看他人轉帳明細 |
| 作為用戶,我想設定常用帳號 | 作為攻擊者,我想透過 CSRF 讓受害者新增我的帳號為常用帳號 |
功能:商品評論
| 正常使用者故事 | Abuse Case |
|---|---|
| 作為買家,我想留下商品評論 | 作為攻擊者,我想在評論中植入 Stored XSS |
| 作為買家,我想上傳評論附圖 | 作為攻擊者,我想透過圖片的 EXIF 資訊進行 XXE 攻擊 |
| 作為店家,我想回覆評論 | 作為競爭對手,我想用機器人大量灌入負面評論 |
飛飛觀點:
每寫一條使用者故事,就寫至少兩條 Abuse Case。
這不是悲觀,這是專業。
消防員不會因為「覺得不會失火」就不帶滅火器。
四、安全驗收標準:讓安全需求「可測試」
安全需求寫得再漂亮,如果沒辦法驗證,就只是一句美麗的口號。
安全驗收標準就是把模糊的安全需求,轉化成可以回答「是或否」的測試條件。
4.1 從模糊到精確
| 模糊的安全需求(不好) | 精確的安全驗收標準(好) |
|---|---|
| 密碼要夠強 | 密碼至少 12 碼,包含大寫、小寫、數字、特殊符號各至少一個 |
| 要防止暴力破解 | 同一帳號連續 5 次登入失敗,鎖定 15 分鐘;同一 IP 每分鐘最多嘗試 10 次 |
| 資料要加密 | 靜態資料使用 AES-256 加密;傳輸中資料使用 TLS 1.2 以上 |
| 要有權限控制 | 一般用戶無法存取 <code>/admin/*</code> 路徑;API 回應中不包含其他用戶的資料 |
| 要記錄日誌 | 登入成功/失敗、權限變更、資料匯出等操作須記錄,日誌保留 90 天 |
4.2 安全驗收標準的寫法公式
每一條安全驗收標準都應該包含三個要素:
【Given】在什麼情境下
【When】發生什麼事
【Then】系統應該怎麼回應
這就是 BDD(Behavior-Driven Development)的 Given-When-Then 格式,但我們把它用在安全情境上。
範例:防止暴力破解
Scenario: 帳號鎖定機制
Given 使用者 "test@example.com" 存在於系統中
When 連續以錯誤密碼嘗試登入 5 次
Then 系統應回傳「帳號已暫時鎖定,請 15 分鐘後再試」
And 第 6 次即使輸入正確密碼也應拒絕登入
And security_log 中應記錄 5 次失敗紀錄與鎖定事件
範例:防止越權存取(IDOR)
Scenario: 使用者無法查看他人訂單
Given 使用者 A 已登入,擁有訂單 #1001
And 使用者 B 擁有訂單 #1002
When 使用者 A 嘗試存取 GET /api/orders/1002
Then 系統應回傳 HTTP 403 Forbidden
And 回應內容不得包含訂單 #1002 的任何資料
範例:防止 SQL Injection
Scenario: 搜尋功能抵擋 SQL Injection
Given 系統提供商品搜尋 API
When 使用者在搜尋欄輸入 "' OR 1=1; --"
Then 系統應正常回傳空結果或無匹配商品
And 不得回傳資料庫錯誤訊息
And 不得回傳非預期的大量資料
範例:敏感資料處理
Scenario: API 不洩露密碼欄位
Given 使用者 A 已登入
When 使用者 A 存取 GET /api/users/me
Then 回應 JSON 不得包含 "password" 欄位
And 回應 JSON 不得包含 "password_hash" 欄位
And 身分證字號應以遮蔽格式回傳(如 A123****89)
4.3 針對 Abuse Case 撰寫驗收標準
還記得前面的 Abuse Case 嗎?每一條 Abuse Case 都應該對應至少一條安全驗收標準:
Abuse Case:攻擊者上傳偽裝的後門程式
Scenario: 檔案上傳安全驗證
Given 系統提供圖片上傳功能
When 使用者上傳一個副檔名為 .jpg 但內容為 PHP 的檔案
Then 系統應拒絕上傳並回傳「檔案格式不支援」
And 系統不得僅依副檔名判斷檔案類型,須驗證 MIME Type 與 Magic Number
And 上傳的檔案須經過 ClamAV 掃描
And 檔案須儲存於非 Web 可直接存取的目錄
Abuse Case:攻擊者透過評論植入 XSS
Scenario: 商品評論防禦 XSS
Given 系統提供商品評論功能
When 使用者在評論中輸入 "<script>alert('XSS')</script>"
Then 評論應正常儲存,但顯示時 HTML 標籤須被轉義
And 頁面不得執行任何注入的 JavaScript
And Content-Security-Policy Header 應限制 inline script 執行
五、安全需求規格書的完整模板
把前面學到的觀念整合起來,以下是一個完整的安全需求規格模板。你可以直接用在你的專案中:
# [功能名稱] 安全需求規格
## 1. 功能概述
- 簡短描述這個功能做什麼
## 2. 使用者故事
- 作為 [角色],我想要 [功能],以便 [價值]
## 3. Abuse Cases(濫用情境)
| 編號 | 攻擊者角色 | 攻擊行為 | 惡意目的 | 風險等級 |
|------|-----------|---------|---------|---------|
| AC-01 | 外部攻擊者 | ... | ... | 高/中/低 |
| AC-02 | 惡意用戶 | ... | ... | 高/中/低 |
## 4. 安全需求
### 4.1 認證與授權
- 此功能需要哪種認證?(JWT / Session / API Key)
- 哪些角色可以使用?(Admin / User / Guest)
### 4.2 輸入驗證
- 各欄位的驗證規則(型態、長度、格式、白名單)
- 伺服器端驗證(必須,不能只靠前端)
### 4.3 資料保護
- 哪些欄位是敏感資料?如何加密或遮蔽?
- 傳輸過程是否強制 HTTPS?
### 4.4 錯誤處理
- 錯誤訊息是否避免洩露系統內部資訊?
- 是否有統一的錯誤回應格式?
### 4.5 日誌與稽核
- 哪些操作需要記錄?
- 日誌中是否排除敏感資料(密碼、Token)?
### 4.6 速率限制
- API 是否設定 Rate Limit?
- 閾值是多少?超過時如何回應?
## 5. 安全驗收標準
| 編號 | 對應 Abuse Case | 驗收條件 (Given-When-Then) | 測試方式 |
|------|----------------|--------------------------|---------|
| SAC-01 | AC-01 | Given...When...Then... | 自動化/手動 |
| SAC-02 | AC-02 | Given...When...Then... | 自動化/手動 |
## 6. 相關法規與標準
- 個資法適用條款
- OWASP Top 10 對應項目
- 產業特定規範(如金管會、衛福部)
六、實戰案例:台灣電商網站的退貨功能
讓我們用一個完整的案例,把前面學到的所有觀念串起來。
功能概述
某台灣電商平台要開發「線上退貨申請」功能,買家可以在訂單頁面申請退貨,上傳商品照片,填寫退貨原因,系統自動計算退款金額。
使用者故事
作為買家,我想要在線上申請退貨並上傳商品照片,以便不用跑實體店面就能完成退貨。
作為客服,我想要審核退貨申請與照片,以便判斷是否符合退貨條件。
作為系統,退貨通過後自動計算退款金額並退回原付款方式。
Abuse Cases
| 編號 | 攻擊者角色 | 攻擊行為 | 惡意目的 | 風險等級 |
|---|---|---|---|---|
| AC-01 | 惡意買家 | 竄改退貨 API 的訂單金額參數 | 取得超額退款 | 高 |
| AC-02 | 外部攻擊者 | 上傳偽裝成圖片的 Web Shell | 取得伺服器控制權 | 高 |
| AC-03 | 惡意買家 | 修改 URL 中的訂單 ID 查看/操作他人退貨申請 | 竊取他人個資或干擾退貨流程 | 高 |
| AC-04 | 外部攻擊者 | 在退貨原因欄位植入 XSS Payload | 竊取客服人員的 Session Cookie | 中 |
| AC-05 | 惡意買家 | 對退貨 API 發送大量請求 | 造成系統負載過重、阻斷服務 | 中 |
| AC-06 | 惡意買家 | 重複提交同一筆退貨申請 | 取得多次退款 | 高 |
安全需求
認證與授權:
- 退貨 API 須驗證 JWT Token,且 Token 中的 <code>user_id</code> 需與訂單所有者一致。
- 客服審核 API 需驗證角色為 <code>customer_service</code> 或 <code>admin</code>。
- 退款金額由後端根據訂單資料庫計算,前端傳送的金額參數不得採信。
輸入驗證:
- 退貨原因文字限 500 字以內,禁止 HTML 標籤。
- 上傳照片僅接受 .jpg、.png,單檔上限 5MB,最多 5 張。
- 照片須驗證 MIME Type 與 Magic Number,禁止副檔名偽裝。
資料保護:
- API 回應中,買家僅能看到自己的退貨申請。
- 退貨紀錄中的付款資訊以遮蔽格式顯示(如信用卡 <code>**** **** **** 1234</code>)。
日誌與稽核:
- 記錄每筆退貨申請的建立、審核、退款操作。
- 日誌中不得包含完整信用卡號或 CVV。
速率限制:
- 同一用戶每小時最多提交 3 筆退貨申請。
- 同一 IP 每分鐘最多 30 次 API 請求。
冪等性設計:
- 退貨申請使用唯一的冪等鍵(Idempotency Key),防止重複提交導致多次退款。
安全驗收標準
# SAC-01:防止退款金額竄改(對應 AC-01)
Scenario: 後端計算退款金額,忽略前端參數
Given 訂單 #2001 的實際金額為 NT$1,500
When 攻擊者在退貨 API 請求中將 refund_amount 改為 15,000
Then 系統應根據資料庫的訂單金額計算退款為 NT$1,500
And 忽略請求中的 refund_amount 參數
# SAC-02:防止惡意檔案上傳(對應 AC-02)
Scenario: 拒絕偽裝成圖片的惡意檔案
Given 系統提供退貨照片上傳功能
When 攻擊者上傳副檔名為 .jpg 但內容為 PHP 的檔案
Then 系統應拒絕上傳並回傳錯誤
And 上傳的檔案不得被存放於 Web Root 目錄下
# SAC-03:防止越權存取(對應 AC-03)
Scenario: 使用者無法操作他人的退貨申請
Given 買家 A 的退貨申請編號為 #R-5001
When 買家 B 嘗試存取 GET /api/returns/R-5001
Then 系統應回傳 HTTP 403
And 回應中不得包含退貨申請 #R-5001 的任何資料
# SAC-04:防止 XSS 攻擊(對應 AC-04)
Scenario: 退貨原因欄位防禦 XSS
Given 買家在退貨原因中輸入 "<img src=x onerror=alert(1)>"
When 客服人員查看此退貨申請
Then 頁面上應顯示轉義後的純文字,不得執行 JavaScript
And HTTP Response 包含 Content-Security-Policy Header
# SAC-05:防止重複退款(對應 AC-06)
Scenario: 冪等鍵防止重複退貨申請
Given 買家對訂單 #2001 提交退貨申請,冪等鍵為 "abc-123"
When 買家使用相同冪等鍵再次提交退貨申請
Then 系統應回傳第一次申請的結果
And 資料庫中僅存在一筆退貨申請
七、將安全需求融入團隊日常的實務建議
知道怎麼寫是一回事,讓團隊真的去寫又是另一回事。以下是讓安全需求規格書真正落地的務實做法:
第一步:在 Sprint Planning 加入「安全腦暴」環節
每次 Sprint Planning 討論新功能時,花 10 分鐘做 Abuse Case 腦力激盪。規則很簡單——每個人輪流說一句「作為攻擊者,我會…」,不管多天馬行空都記下來,之後再過濾優先順序。
這個環節的重點不是找到所有攻擊,而是培養團隊用攻擊者角度思考的習慣。就像武術訓練不是為了打架,而是讓身體記住防禦的反射。
第二步:建立安全需求 Checklist
不是每個功能都需要從零開始想安全需求。準備一份 Checklist,讓開發者對照確認:
□ 此功能是否涉及使用者認證?→ 確認認證機制
□ 此功能是否接受使用者輸入?→ 定義輸入驗證規則
□ 此功能是否處理敏感資料?→ 確認加密與遮蔽方式
□ 此功能是否有檔案上傳?→ 定義檔案類型與大小限制
□ 此功能是否涉及金流?→ 確認冪等性與金額驗證
□ 此功能是否有權限區分?→ 定義各角色的存取範圍
□ 此功能是否對外暴露 API?→ 定義 Rate Limit 與認證方式
□ 此功能的錯誤訊息是否可能洩露系統資訊?→ 定義錯誤回應格式
第三步:讓安全驗收標準成為 Definition of Done 的一部分
在團隊的 Definition of Done(DoD)中加入:
✅ 功能需求已完成
✅ 單元測試通過
✅ Code Review 通過
✅ 安全需求已定義且通過審查 ← 加這個
✅ 安全驗收標準測試通過 ← 加這個
當安全驗收標準成為「完成的定義」之一,團隊就不會把它當成「有空再做」的事了。
第四步:自動化安全驗收測試
很多安全驗收標準可以寫成自動化測試,整合進 CI/CD Pipeline:
// 使用 Jest + Supertest 測試安全驗收標準
describe('SAC-03: 防止越權存取', () => {
it('使用者無法查看他人退貨申請', async () => {
// Given: 買家 B 的 Token
const tokenB = await loginAs('buyer_b@example.com');
// When: 嘗試存取買家 A 的退貨申請
const response = await request(app)
.get('/api/returns/R-5001')
.set('Authorization', <code class="kb-btn">Bearer ${tokenB}</code>);
// Then: 應回傳 403
expect(response.status).toBe(403);
expect(response.body).not.toHaveProperty('refund_amount');
expect(response.body).not.toHaveProperty('reason');
});
});
describe('SAC-04: 防止 XSS', () => {
it('退貨原因中的 HTML 標籤應被轉義', async () => {
const token = await loginAs('buyer_a@example.com');
const maliciousInput = '<script>alert("XSS")</script>';
// When: 提交含有 XSS payload 的退貨申請
const createResponse = await request(app)
.post('/api/returns')
.set('Authorization', <code class="kb-btn">Bearer ${token}</code>)
.send({ order_id: '2001', reason: maliciousInput });
// Then: 讀取時應為轉義後的文字
const getResponse = await request(app)
.get(<code class="kb-btn">/api/returns/${createResponse.body.id}</code>)
.set('Authorization', <code class="kb-btn">Bearer ${token}</code>);
expect(getResponse.body.reason).not.toContain('<script>');
});
});
八、常見問題 FAQ
Q1:每個功能都要寫 Abuse Case 嗎?不會太花時間?
不需要每個功能都寫到鉅細靡遺。建議根據風險等級來決定深度:
| 風險等級 | 功能類型 | Abuse Case 深度 |
|---|---|---|
| 高 | 涉及金流、個資、認證、檔案上傳 | 完整 Abuse Case + 安全驗收標準 |
| 中 | 涉及使用者輸入、API 對外暴露 | 至少 2-3 條 Abuse Case |
| 低 | 純展示性頁面、靜態內容 | 快速 Checklist 確認即可 |
重點不是寫多少,而是養成思考的習慣。
Q2:我不是資安專家,怎麼知道該防什麼?
你不需要是資安專家。參考以下資源就能涵蓋八成以上的常見威脅:
- OWASP Top 10:每個 Web 開發者都該知道的十大風險
- OWASP ASVS(Application Security Verification Standard):更詳細的安全驗證標準
- OWASP Cheat Sheet Series:各種安全主題的防禦速查表
從這些資源出發,對照你的功能,就能列出大部分需要防範的攻擊。
Q3:安全需求跟功能需求衝突怎麼辦?
最常見的衝突是「使用者體驗 vs. 安全性」。例如:密碼太複雜使用者記不住,二次驗證太麻煩使用者不想用。
解法是根據風險等級做分級:
- 轉帳、修改密碼等高風險操作:安全優先,即使犧牲些便利性
- 瀏覽商品、加入購物車等低風險操作:體驗優先,安全在背景進行
安全和體驗不是非此即彼,而是在不同情境下找到合適的平衡點。
Q4:既有的舊專案怎麼補寫安全需求?
不要試圖一次補完所有功能的安全需求。建議的優先順序:
- 最先補:處理金流、個資的功能
- 其次補:對外暴露的 API、認證相關功能
- 再其次:有使用者輸入的功能
- 最後補:內部工具、管理後台
每次迭代時,順帶補上你正在修改的功能的安全需求,逐步累積。
九、結語:安全需求不是額外工作,是需求的完整表達
很多開發者把安全需求當成「額外的負擔」,但換個角度想——你寫的功能需求說「使用者可以登入」,卻沒說密碼怎麼存,這其實是需求不完整,不是安全問題。
安全需求規格書的本質,是讓需求從「能用」進化到「能安全地用」。
就像建築師不會只畫出房間的位置而不標示防火通道和逃生路線,軟體工程師也不應該只定義功能而不定義防護。
從今天開始,每寫一條使用者故事,就多問自己一句:
「如果攻擊者看到這個功能,他會怎麼做?」
這個習慣,就是安全需求的起點。
延伸閱讀
[安全需求] 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。
具體做法如下:
-
CI 驗證機制:
- 於 Pull Request(PR)提交時,自動檢查是否附上 spec.md。
- 若規格未更新或安全欄位為空,PR 自動退回。
- 可使用 GitHub Actions、GitLab CI 或 Jenkins pipeline 實現。
-
規格自動比對(Spec Diff):
- 每次修改 PR 時,CI 自動比較規格前後版本,
若發現安全條件被刪除(例如移除了「JWT 認證」),
則標記 [SECURITY WARNING]。
- 每次修改 PR 時,CI 自動比較規格前後版本,
-
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 不是魔法,它仍需要人的設計與判斷。
但它讓安全有了新的可能:
把「意圖」轉成「行動」,把「防護」寫進「規格」。
當安全能被設計、被追蹤、被再生,
安全文化就不再只是喊口號——而是每天都在發生。