💡 今日學習目標:深入學習 SEI (Software Engineering Institute) 前五大安全程式碼實務法則,建立防禦性程式設計底層思維。
卡內基梅隆大學 SEI 歸納的 Top 10 Secure Coding Practices,是全球軟體界公認的最權威程式碼安全指南之一。
不論你使用的是 C#、Java、Python、JavaScript 還是 Go,這 10 大法則都是跨語言萬國通用的防守鐵律。
今天,我們就來拆解前五法則的精髓與跨語言邏輯示範!

// ❌ 黑名單檢查(容易被繞過)
If userInput.Contains("<script>"): // 攻擊者可用 <sCrIpT> 或 <img src=x onerror=...> 輕易繞過
Return Error
// ✅ 白名單檢查(嚴格規範合法格式)
If NOT Regex.IsMatch(userInput, "^[a-zA-Z0-9_]{3,20}$"):
Return Error("Invalid Username Format")
⚠️ 用正規表達式做白名單,有兩個坑一定要避開:
1. 錨點要用對,而 Ruby 要特別小心。
在 Python、Java、.NET、PHP 裡,
$匹配的是「字串結尾」或「結尾換行符之前」。也就是說admin\n<script>…這種輸入,有機會通過^[a-zA-Z0-9_]+$的檢查。要真的鎖住整串,Python 用\Z,Java / .NET / PHP 用\z。Ruby 的狀況更嚴重一層:它的
^與$永遠是「行錨點」,沒有例外,也不需要任何旗標(Ruby 的/m只影響.能不能吃換行)。所以/^[a-zA-Z0-9_]+$/的真正意思是:只要輸入裡「有任何一行」長得像使用者名稱,就通過。這代表只換結尾錨點是不夠的。
/^[a-zA-Z0-9_]+\z/拿去比對"evil\nadmin"依然會過,因為^跑去匹配第二行的開頭了。Ruby 必須頭尾一起換掉,用\A與\z:
/\A[a-zA-Z0-9_]{3,20}\z/(JavaScript 與 Go 沒有這個問題:
$就是字串結尾,除非你自己開了多行模式。)2. 小心 ReDoS。 巢狀量詞(例如
(a+)+)遇到精心構造的輸入時,會讓正規引擎陷入指數級回溯,一支請求就能把 CPU 吃滿,這正是 Day 04 冰山圖裡水面下的 ReDoS。
白名單規則寫得越簡單越好,這剛好也呼應了等一下要講的法則 4。
-Wall -Wextra -Werror、TypeScript 開 strict、Python 用 mypy --strict、C# 開 TreatWarningsAsErrors)。// ❌ 不安全的邏輯:預設允許,特定條件才拒絕
Function CanAccessResource(user, resource):
If user.IsBanned:
Return False
Return True // 預設放行!容易漏掉未考慮到的邊界情況
// ✅ 安全防守邏輯:預設拒絕,只有明確授權才允許
Function CanAccessResource(user, resource):
If user.HasPermission(resource.RequiredPermission):
Return True // 明確授權
Return False // 預設全部拒絕
💬 明日預告:【Day 14】SEI 10 大安全程式碼法則 (下):最小權限 (Least Privilege) 與縱深防禦
明天我們將繼續解析 SEI 後五大黃金法則,從最小權限一路談到縱深防禦!