iT邦幫忙

2026 iThome 鐵人賽

DAY 22
1
Security

槍林彈雨下的資安防守:從品質觀念切入,帶開發者從零動手作資安 30 天系列 第 22

【Day 22】駭客只需要成功一次,我們必須每次都成功:安全架構設計思維

  • 分享至 

  • xImage
  •  

💡 今日學習目標:踏入階段四「資安是設計出來的」,理解「駭客只需成功一次,防守者必須每次都成功」這句話的真正份量,並掌握 Security by Design 三大防守柱石:信任邊界、最小攻擊面、故障安全。


📌 前言:一句 1984 年的話,怎麼變成了資安圈的口頭禪

階段三我們拆過 SEI 十大法則、也拆過六個 OWASP Top 10 的真實漏洞。從今天開始,我們要往上拉一層,進到架構設計的視野,也就是階段四:資安是「設計」出來的。

在正式開始之前,先說一個你可能沒想到的冷知識。

資安圈很愛引用這句話:

「防守者必須每次都成功,攻擊者只需要成功一次。」

這句話最早不是出自哪位資安大師,而是 1984 年愛爾蘭共和軍(IRA)在英國布萊頓飯店炸彈案之後發出的聲明

那是一起真實的恐怖攻擊:1984 年 10 月 12 日凌晨,炸彈在保守黨年會下榻的布萊頓大飯店引爆,造成五人死亡、三十餘人受傷。但 IRA 鎖定的目標、當時也住在該飯店的英國首相柴契爾夫人並未受傷。事後 IRA 放話:

"Today we were unlucky, but remember, we only have to be lucky once. You will have to be lucky always."
(今天我們運氣不好,但記住,我們只需要幸運一次,你們必須永遠幸運。)

四十年後,資安圈把這句話原封不動地借了過來,因為它精準地道出了防守者的結構性劣勢:攻擊者只要找到一個沒被顧到的縫,遊戲就結束;防守者卻得把每一個縫都堵住,而且要一直堵下去。

這不是一句用來嚇唬人的口號。2019 年,這句話在一家美國大型銀行身上,變成了活生生的現實。


🔍 一個縫,怎麼變成一億筆資料外洩:Capital One 事件

2019 年 3 月 22 至 23 日,美國 Capital One 銀行遭到攻擊(但直到 7 月才被發現),超過 1 億筆美國與加拿大客戶的信用卡申請資料(含社會安全碼、銀行帳戶)被竊取。攻擊者不是國家級駭客組織,是一名前 AWS 員工,手法也不是什麼驚天動地的 0-day,是我們在 Day 21 才學過的 SSRF

代價分成兩筆:隔年(2020 年 8 月)遭美國財政部通貨監理署(OCC)處以 8,000 萬美元民事罰款,聯準會同時發出停止命令但未另行罰款;之後在 2021 年,再以 1.9 億美元與受害客戶達成集體訴訟和解。

🧭 這兩筆的性質完全不同,值得分清楚:罰款是監理機關認定你的風險管理有缺失而開的罰單,錢繳給政府;和解則是賠給被害人的錢。OCC 開罰的理由寫得很直白:在把大量 IT 營運搬上公有雲之前,沒有建立有效的風險評估流程,事後也沒有及時修正缺失。

換句話說,罰的不是「你被駭了」,而是「你在上雲之前沒有想清楚」。這正是今天整篇要談的事。

事情的經過,剛好就是三個小小的架構疏忽疊在一起:

  1. Capital One 對外的 WAF(Web 應用防火牆)存在 SSRF 漏洞,攻擊者能誘騙它去對內部發送請求。
  2. 攻擊者利用這個 SSRF,讓 WAF 去問 AWS 執行個體中繼資料服務(Instance Metadata Service) 要一組 IAM 憑證。
  3. 這組憑證,因為掛在 WAF 上的 IAM 角色權限遠超過它的職責,竟然能列出並讀取 700 多個 S3 儲存桶,於是超過一億筆資料被整批捲走。

📖 資料來源:美國司法部起訴書新聞稿OCC 裁罰新聞稿(2020-08,含裁罰理由原文)Wiz Cloud Threat Landscape — Capital One Incident (March 2019)

事後檢討會發現:光靠 Day 21 教的「防 SSRF」本身,救不了這個案子。 就算 WAF 那個漏洞本身很難完全杜絕,只要架構上再多顧到一件事(中繼資料服務不該對這個角色開放,或者這個角色的權限被限制在真正需要的範圍),這 1 億筆資料就不會被整批捲走。

這就是「資安是設計出來的」這句話的意思:程式碼層級的漏洞總會發生,但架構設計決定了一個漏洞會停在原地,還是會被放大成災難。


🏛️ 核心原理:Security by Design 三大防守柱石

原生安全設計(Security by Design),指的是在畫系統架構圖、規劃資料庫 Schema、定義 API 介面的第一天,就把資安考量寫進架構骨幹裡,而不是等系統快上線了才臨時補。

拿 Capital One 案例來對照,剛好可以看到三大柱石同時失守:

Security by Design 三大防守柱石,對照 2019 年 Capital One 事件的三個架構疏忽

柱石 1:明確劃分信任邊界(Trust Boundaries)

系統中不同組件的交界處(前端 ↔ 後端 API ↔ 內網服務 ↔ 第三方 API)就是「信任邊界」。跨越邊界的每一次資料交換,都必須經過強制的認證與授權,不能假定「反正是內網」就一定安全。

Capital One 的問題正出在這裡:WAF 本來站在「公網」與「內網」的邊界上,但它向 AWS Metadata 服務發出請求時,沒有人把這條邊界當一回事:外部輸入(那個被 SSRF 誘騙的請求)直接穿越了公網/內網的邊界,中間沒有任何重新檢查的關卡。

這正是 Day 05 規劃 SDLC 設計階段時就埋下的那條 CheckList 題目:「系統模組之間的信任邊界在哪裡?」。當時看起來像是一句空泛的提醒,此刻你應該能感受到它的重量了。

柱石 2:最小化攻擊面(Minimize Attack Surface)

系統暴露給外面的介面、Port、內部服務越少,駭客能下手的機會就越少。架構實踐上,包括關閉不必要的 Port 與 Endpoint、禁用 Debug 模式,以及最容易被忽略的一項:對外元件能拿到的內部資源,要限縮在完成任務所需的最小範圍

Capital One 那個 WAF 掛載的 IAM 角色,權限遠遠超過「當一個防火牆」所需要的範圍,讓它可以列出並讀取 700 多個原本毫不相干的 S3 儲存桶。這個角色的攻擊面,比它實際需要的大了好幾個數量級,一旦這個元件被攻破,攻擊者能拿到的東西也跟著等比放大。

柱石 3:故障安全設計(Fail-Safe Defaults)

系統發生例外、逾時或崩潰時,預設狀態必須是「安全且封閉」,絕對不能是照常放行。

// ❌ 壞設計:例外發生時洩漏詳細堆疊或直接放行
Function AccessResource():
    Try:
        VerifySignature()
    Catch Exception ex:
        // 🚨 發生例外時忘記阻止,程式繼續往下執行!
        Log(ex)

    Return GetSensitiveData()

// ✅ 安全設計:Fail-Closed(例外即封鎖)
Function AccessResource():
    Try:
        If NOT VerifySignature():
            Return Error(403, "Forbidden")
    Catch Exception ex:
        // 🛡️ 發生例外時,記載內部 Log,並對外部預設拒絕
        LogSystemError(ex)
        Return Error(500, "Internal Error")

    Return GetSensitiveData()

這不是哪個資安顧問今天發明的說法。「Fail-safe defaults(故障安全預設)」是 Saltzer 與 Schroeder 在 1975 年發表的經典論文〈The Protection of Information in Computer Systems〉裡提出的八大安全設計原則之一。半個世紀前就講清楚了,系統的預設狀態應該是拒絕,而不是允許。

📖 資料來源:J. H. Saltzer, M. D. Schroeder, The Protection of Information in Computer Systems, Proceedings of the IEEE, Vol. 63, No. 9, 1975.(八大設計原則在第一節 Basic Principles of Information Protection)

Capital One 事件裡最終的補救,剛好就是把這個原則落地:AWS 後續推出了 IMDSv2,要求呼叫端必須先用 Session Token 換取存取權,才能讀取中繼資料,把整套機制從「預設開放、誰問都答」,改成「預設拒絕,沒有 Token 免談」。


💡 常見誤解:「Security by Design 就是花錢請顧問畫一次性的架構審查」

很多團隊聽到「安全架構設計」,直覺反應是找資安顧問來開一次會、畫一張架構圖、簽一份審查報告,然後就當作這件事「做完了」。

這是最容易踩的誤解。 Capital One 的架構在出事之前,一樣通過了雲端安全稽核。問題從來不是「當初沒人審查過架構」,而是:

  • 三大柱石不是三個一次性動作,是每一次新增元件、新增 API、調整 IAM 權限時都要重新問一遍的日常習慣。
  • 信任邊界會隨著系統演進而改變:今天多接一個第三方服務、多開一個內部 API,就是多一條需要重新檢視的邊界。
  • 最小攻擊面尤其會隨時間悄悄變大:一個角色一開始權限給得剛好,半年後為了「順便解決另一個問題」多加了幾條權限,攻擊面就這樣一點一滴膨脹,直到某天被人利用。

也正因為如此,Day 15 提到 OWASP 的 Insecure Design(不安全設計) 排名近幾年在下滑,OWASP 官方給出的解讀是「業界在威脅建模與安全設計上有了明顯進步」。這件事沒有一次性的終點,做得好的團隊,是把它變成了持續進行的習慣,而不是開發流程裡的一次性關卡。


🎯 今日重點小結與防守心法

  • 🔹 心法 1:一個縫,可以被架構疏忽放大成災難。Capital One 案例告訴我們,程式碼層級的漏洞或許無法百分之百杜絕,但架構設計決定了它會停在原地,還是會演變成上億筆資料外洩。
  • 🔹 心法 2:三大柱石要同時顧到。信任邊界劃清楚、攻擊面收到最小、故障時預設拒絕。Capital One 剛好是三個同時失守才釀成大禍,顧好任何一個都可能擋下這次攻擊。
  • 🔹 心法 3:這是持續的習慣,不是一次性審查。每加一個 API、每調一次 IAM 權限,都要重新用這三大柱石檢視一次。

💬 明日預告:【Day 23】【動手做】資安新手的第一個威脅建模 (Threat Modeling):STRIDE 模型演練
明天我們將動手演練微軟最知名的威脅建模框架:STRIDE 模型!


上一篇
【Day 21】【動手做】SSRF 伺服端請求偽造:為什麼 2025 把它併進了 A01
系列文
槍林彈雨下的資安防守:從品質觀念切入,帶開發者從零動手作資安 30 天22
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
AndyAWD
iT邦新手 1 級 ‧ 2026-09-10 23:45:45

防守者必須每次都成功,攻擊者只需要成功一次。

說的真好

我要留言

立即登入留言