Luke a Pro

Luke Sun

Developer & Marketer

🇺🇦
EN||

如何建立安全判斷能力

| , 8 minutes reading.

1. 為什麼要關注這個?

你已經學會了演算法,了解了陷阱。但安全不是一份清單——而是一種判斷。

每個安全決策都是成本、可用性和保護級別之間的權衡。沒有「完美安全」——只有「對這個威脅模型足夠安全」。

這篇文章教你如何思考安全,而不僅僅是實現它。

2. 安全思維

開發者 vs. 安全工程師

開發者思維:
「我如何讓這個功能運作?」
- 關注功能
- 正向路徑思考
- 信任輸入
- 假設使用者善意

安全思維:
「這個怎麼能被破解?」
- 關注失敗模式
- 對抗性思考
- 不信任一切
- 假設惡意意圖

像攻擊者一樣思考

對於每個功能,問:
1. 這做了什麼假設?
2. 如果這些假設是錯的呢?
3. 誰能存取什麼?
4. 最壞情況會怎樣?
5. 如果我是惡意的,我會怎麼利用這個?

例子:密碼重設
開發者:「使用者點擊連結,輸入新密碼,完成。」
攻擊者:
- 如果我攔截了郵件呢?
- 如果我猜到重設令牌呢?
- 如果我請求重設別人的密碼呢?
- 如果我使用令牌兩次呢?
- 如果我在請求重設後更改郵箱呢?

偏執的問題

部署任何功能之前:

認證:
- 有人能以另一個使用者身份認證嗎?
- 如果憑證被盜會發生什麼?
- 嘗試有速率限制嗎?

授權:
- 使用者能存取其他人的資料嗎?
- ID 是否可猜測?
- 每一層都檢查了權限嗎?

資料處理:
- 資料在哪裡以明文形式存在?
- 誰能存取加密金鑰?
- 日誌裡有什麼?

失敗模式:
- 出問題時會發生什麼?
- 錯誤訊息會洩露資訊嗎?
- 有安全的降級方案嗎?

3. 威脅建模

什麼是威脅模型?

威脅模型回答:
1. 我們在保護什麼?(資產)
2. 誰可能攻擊它?(威脅行為者)
3. 他們可能如何攻擊?(攻擊向量)
4. 可能出什麼問題?(影響)
5. 我們如何預防?(緩解措施)

沒有威脅模型,你要麼:
- 防禦不存在的威脅
- 遺漏存在的威脅
- 低效地分配資源

STRIDE 框架

微軟的 STRIDE 分類:

S - Spoofing(欺騙)
    假冒他人身份
    緩解:認證

T - Tampering(竄改)
    修改資料或程式碼
    緩解:完整性檢查、簽章

R - Repudiation(抵賴)
    否認所做的操作
    緩解:日誌、稽核追蹤

I - Information Disclosure(資訊洩露)
    暴露機密資料
    緩解:加密、存取控制

D - Denial of Service(阻斷服務)
    使系統不可用
    緩解:速率限制、冗餘

E - Elevation of Privilege(權限提升)
    獲取未授權存取
    緩解:最小權限、沙箱

實用威脅建模

步驟 1:畫出系統
┌──────────┐     ┌──────────┐     ┌──────────┐
│   用戶端  │────▶│   API    │────▶│  資料庫   │
└──────────┘     └──────────┘     └──────────┘


                 ┌──────────┐
                 │   快取   │
                 └──────────┘

步驟 2:標記信任邊界
┌─────────────────────────────────────────────┐
│ 不受信任                                     │
│  ┌──────────┐                               │
│  │  用戶端   │                               │
│  └──────────┘                               │
└─────────────────────────────────────────────┘
          │ 信任邊界

┌─────────────────────────────────────────────┐
│ 受信任(但要驗證)                            │
│  ┌──────────┐     ┌──────────┐              │
│  │   API    │────▶│  資料庫   │              │
│  └──────────┘     └──────────┘              │
└─────────────────────────────────────────────┘

步驟 3:列出每個邊界的威脅
用戶端 → API:
- 注入攻擊
- 認證繞過
- 速率限制濫用
- 資料竄改

API → 資料庫:
- SQL 注入
- 權限提升
- 資料洩露

威脅行為者畫像

不同攻擊者有不同的能力:

腳本小子:
- 使用現成工具
- 低複雜度
- 大量攻擊
- 防禦:基本安全衛生

網路犯罪分子:
- 財務動機
- 中等複雜度
- 針對性攻擊
- 防禦:強認證、監控

國家級行為者:
- 無限資源
- 高級能力
- 戰略目標
- 防禦:縱深防禦,假設已被入侵

內部人員:
- 已有存取權限
- 了解系統
- 利用信任
- 防禦:最小權限、稽核日誌

你的威脅模型是什麼?
個人部落格不需要防國家級攻擊。
處理數十億的銀行需要。

4. 評估風險

風險 = 機率 × 影響

                    │   低機率         │   高機率         │
────────────────────┼──────────────────┼─────────────────┤
高影響              │   監控          │   立即修復       │
────────────────────┼──────────────────┼─────────────────┤
低影響              │   接受          │   最終修復       │
────────────────────┴──────────────────┴─────────────────┘

評估範例:

登入中的 SQL 注入:
- 機率:高(常見攻擊)
- 影響:高(完全資料庫存取)
- 優先級:立即修復

比較中的時序攻擊:
- 機率:低(需要精確度)
- 影響:中(憑證洩露)
- 優先級:最終修復

管理面板中的 XSS:
- 機率:低(有限使用者)
- 影響:高(帳戶接管)
- 優先級:監控/修復

安全的經濟學

攻擊者也做成本效益分析:

攻擊成本 vs. 目標價值

低價值目標 + 高攻擊成本 = 安全
高價值目標 + 低攻擊成本 = 被攻破

你的目標:
1. 降低目標價值(最小化儲存的資料)
2. 增加攻擊成本(更好的安全)
3. 減少攻擊者回報(限制爆炸半徑)

真實例子:
- 目標:密碼資料庫
- 無雜湊:一次洩露 = 所有憑證
- 使用 bcrypt:一次洩露 = 每個密碼需要數月破解
- 攻擊成本增加 1000 倍,保護價值相同

什麼是「足夠好」?

安全總是相對於:

1. 你在保護什麼
   - 個人部落格:基本安全
   - 電商:強安全
   - 醫療:合規 + 強安全
   - 國防:最大安全

2. 你在防禦誰
   - 隨機網路:標準實踐
   - 針對性攻擊者:高級措施
   - 國家級:專門防禦

3. 失敗的後果
   - 尷尬:基本保護
   - 財務損失:強保護
   - 安全/生命:最大保護

4. 可用資源
   - 新創公司:優先處理最高風險
   - 企業:全面覆蓋
   - 政府:縱深防禦

「足夠好」= 風險在可用資源內降低到可接受水平

5. 常見安全決策

什麼時候用什麼

密碼儲存:
- 總是:Argon2id 或 bcrypt
- 絕不:MD5、SHA-1、純 SHA-256

對稱加密:
- 預設:AES-256-GCM
- 替代:ChaCha20-Poly1305
- 絕不:DES、3DES、ECB 模式

非對稱加密:
- 金鑰交換:X25519 或 ECDH P-256
- 簽章:Ed25519 或 ECDSA P-256
- 舊式:RSA-2048+ 使用 OAEP

亂數:
- 總是:secrets 模組或 OS CSPRNG
- 絕不:random 模組用於安全

TLS:
- 最低:TLS 1.2
- 首選:TLS 1.3
- 絕不:SSL、TLS 1.0/1.1

決策框架

選擇安全控制時:

1. 業界標準是什麼?
   - 從已建立的最佳實踐開始
   - 只有充分理由才偏離

2. 威脅模型需要什麼?
   - 保護與威脅匹配
   - 不要過度工程

3. 權衡是什麼?
   - 效能影響
   - 可用性影響
   - 維護負擔

4. 失敗模式是什麼?
   - 安全失敗 vs. 開放失敗
   - 優雅降級

5. 我們能偵測到失敗嗎?
   - 日誌和監控
   - 異常告警

安全討論中的危險信號

某人不理解安全的警告信號:

「我們不需要擔心那個」
- 洩露前的名言

「透過隱藏來安全」
- 攻擊者會弄清楚的

「我們以後再加安全」
- 技術債務會累積

「它在防火牆後面」
- 防火牆是一層,不是唯一層

「我們用了[流行詞]所以我們安全了」
- 沒有單一技術能解決安全

「沒人會想攻擊我們」
- 每個人都是目標

「我們的使用者不會那樣做」
- 永遠不要信任使用者行為

「那太不可能發生了」
- 在規模上不可能的事情經常發生

6. 培養你的技能

從洩露事件中學習

每份洩露報告都是一課:

1. 漏洞是什麼?
   - 技術缺陷
   - 流程失敗
   - 人為錯誤

2. 如何被利用?
   - 攻擊技術
   - 使用的工具
   - 利用時間

3. 如何被發現?
   - 監控發現
   - 攻擊者報告
   - 第三方發現

4. 什麼能阻止它?
   - 技術控制
   - 流程改進
   - 培訓

資源:
- Krebs on Security
- Troy Hunt 的部落格
- 公司洩露報告
- CVE 資料庫

練習進攻性安全

理解攻擊有助於建立防禦:

初學者:
- OWASP WebGoat
- HackTheBox 入門點
- TryHackMe 免費房間

中級:
- CTF 比賽
- 漏洞賞金計畫(先只讀)
- 易受攻擊的虛擬機(DVWA、Metasploitable)

高級:
- 程式碼審查找漏洞
- 滲透測試課程
- 安全認證(OSCP)

你不需要成為專家攻擊者。
但理解攻擊能讓你成為更好的防禦者。

安全審查清單

# 程式碼審查時要問的問題

class SecurityReviewChecklist:
    """
    在審查程式碼時用作思維框架。
    """

    authentication = [
        "憑證是否安全儲存(雜湊密碼)?",
        "每個請求都檢查了認證嗎?",
        "工作階段管理是否安全?",
        "有暴力破解保護嗎?",
    ]

    authorization = [
        "是否在正確的層檢查了存取控制?",
        "所有敏感操作都受保護嗎?",
        "遵循了最小權限原則嗎?",
        "使用者能存取其他使用者的資料嗎?",
    ]

    input_handling = [
        "所有輸入都驗證了嗎?",
        "查詢參數化了嗎(沒有 SQL 注入)?",
        "輸出編碼了嗎(沒有 XSS)?",
        "檔案上傳受限制嗎?",
    ]

    cryptography = [
        "使用了標準演算法嗎?",
        "金鑰管理得當嗎?",
        "隨機性來自安全來源嗎?",
        "敏感資料在靜態/傳輸中加密了嗎?",
    ]

    error_handling = [
        "錯誤訊息會洩露資訊嗎?",
        "例外處理是否安全?",
        "系統是否安全失敗?",
        "錯誤是否適當記錄?",
    ]

    data_handling = [
        "儲存了什麼敏感資料?",
        "日誌中有敏感資料嗎?",
        "資料備份如何處理?",
        "需要時資料是否正確刪除?",
    ]

7. 與非安全人員合作

溝通風險

對高階主管:
- 用商業術語說話(風險、成本、影響)
- 使用類比(「這就像讓保險庫敞開」)
- 盡可能量化(「洩露可能造成 X 百萬損失」)
- 呈現帶權衡的選項

對開發者:
- 具體說明漏洞
- 解釋攻擊場景
- 提供具體修復方案
- 不要只說「這不安全」

對使用者:
- 解釋「為什麼」不只是「什麼」
- 讓安全行為變得簡單
- 不要責怪錯誤
- 將安全內建到產品中

何時推回

有時你需要說不:

推回當:
- 截止日期壓力凌駕於安全之上
- 「就這一次」的例外累積
- 安全被當作可選項
- 已知漏洞沒有被修復

如何推回:
- 解釋具體風險
- 提出替代方案
- 記錄決定
- 必要時升級

記錄一切:
「在 [日期],我提出了對 [問題] 的擔憂。
決定是 [接受/推遲]。
風險擁有者:[姓名]。」

建立安全文化

安全是每個人的工作:

對開發者:
- 在程式碼審查中包含安全
- 進行安全培訓
- 讓安全編碼成為預設
- 表揚安全修復

對組織:
- 讓報告漏洞變得安全
- 獎勵安全貢獻
- 在規劃中包含安全
- 從事件中學習而不責備

對產品:
- 預設安全設定
- 清晰的安全文件
- 簡單的安全設定
- 定期安全更新

8. 判斷框架

做安全決策

面對安全決策時:

1. 識別資產
   我們到底在保護什麼?

2. 評估威脅
   誰可能攻擊,如何攻擊?

3. 評估風險
   機率 × 影響

4. 考慮選項
   有哪些緩解措施可用?

5. 權衡利弊
   成本、可用性、維護

6. 決定並記錄
   做出選擇,記錄理由

7. 定期審查
   威脅在變化,定期重新評估

與不確定性共存

安全沒有終點:

接受:
- 完美安全不存在
- 新漏洞會被發現
- 攻擊者在進化他們的技術
- 你的威脅模型可能是錯的

計劃:
- 定期安全審查
- 事件回應
- 持續改進
- 從失敗中學習

記住:
- 今天足夠好明天可能不夠
- 縱深防禦提供韌性
- 偵測和預防同樣重要
- 恢復能力是必須的

9. 總結

三件事要記住:

  1. 像攻擊者一樣思考。 對每個系統,問:「我怎麼能破解這個?」考慮認證繞過、資料存取、信任邊界和失敗模式。防禦者必須處處正確;攻擊者只需要對一次。

  2. 安全是風險管理。 沒有「完美安全」——只有成本、可用性和保護級別之間的權衡。理解你的威脅模型,現實地評估風險,在最重要的地方投入資源。

  3. 透過實踐建立判斷力。 研究洩露事件,練習進攻技術,帶著安全思維審查程式碼,從每個事件中學習。安全判斷來自經驗,不僅僅是知識。

10. 系列結語

你已經走了很長的路:

第一部分:你學會了為什麼密碼學重要以及基本原語。

第二部分:你掌握了對稱加密——AES、操作模式和金鑰衍生。

第三部分:你理解了非對稱密碼學——RSA、Diffie-Hellman 和橢圓曲線。

第四部分:你探索了雜湊、MAC 和數位簽章。

第五部分:你看到了這些元件如何在真實協定中組合——TLS、密碼儲存、金鑰管理。

第六部分:你學會了為什麼好的密碼學還不夠,以及如何全面思考安全。

最重要的一課:密碼學是工具,不是解決方案。 正確使用它,但記住安全是一個系統屬性,需要持續關注程式碼、營運和人的因素。

現在去建構安全的系統吧。當你不確定時,記住:最好的安全決策通常是能夠充分應對威脅模型的最簡單方案。

祝你好運。