1. 威脅
1.1. 威脅常常比事件本身更加可怖
- 1.1.1. 索爾·阿林斯基
1.2. 威脅無處不在
-
1.2.1. 如果妥善管理,我們也可以安然與威脅共存
-
1.2.2. 我們自己沒有幾百萬年進化而來的本能來防禦軟體方面的威脅
1.3. 把視角從軟體構建者轉向攻擊者
-
1.3.1. 理解一個系統的潛在風險是一切的起點
-
1.3.2. 在軟體設計中加入可靠的防禦和緩解措施
1.4. 軟體的本質:它是由一堆程式碼和元件構成的,這些程式碼和元件承擔著資料處理和儲存的職責
1.5. 威脅包含各種可以帶來傷害的方式
-
1.5.1. 刻意發動的對抗性攻擊行為
-
1.5.2. 軟體錯誤
-
1.5.3. 人為錯誤
-
1.5.4. 意外事故
-
1.5.5. 硬體故障
1.6. 很難窮舉大型軟體系統的所有威脅和漏洞
-
1.6.1. 高明的安全工作是逐步提高標準,而不是追求盡善盡美
-
1.6.2. 我們恐怕從來都對那些遭到挫敗的攻擊一無所知,而缺乏反饋機制往往會讓人倍感失望
-
1.6.3. 我們展現出來的安全意識越強,我們就可以看到越多的威脅
1.7. 理解威脅建模可以讓我們把視野從安全性上擴充套件出去,從而重新審視我們的目標系統
2. 對抗性視角
2.1. 人類肇事者才是萬惡之源
- 2.1.1. 安全事件不會自己無緣無故地發生
2.2. 只要對軟體安全性進行協同分析,就一定要考慮可能的對手會進行什麼樣的嘗試,這樣才能預測和防禦潛在的攻擊
-
2.2.1. 不要自欺欺人地認為自己可以準確地預測對手的一舉一動
-
2.2.2. 不要花費大量時間和精力去猜測他們的具體想法
-
2.2.3. 不要自以為是永遠比對手棋高一著的名偵探
2.3. 瞭解攻擊者的思考方式的確有其價值,但我們的目標是開發安全軟體,所以攻擊者具體會透過什麼技術手段來探測、滲透和洩露資料無關緊要
2.4. 軟體錯誤絕對是攻擊者重點關注的物件,因為它們往往就是軟體的弱點所在
-
2.4.1. 攻擊者如果偶然發現了某些明顯的軟體錯誤,他們就會嘗試建立一些變體,看看能不能造成實實在在的破壞
-
2.4.2. 一旦攻擊者發現了漏洞,他們就很有可能把更多時間和精力放在這個漏洞上,因為很多瑕疵都可以被攻擊者藉助協同攻擊擴充套件出嚴重的後果
2.5. 兩項幾乎不會引人注意的細微漏洞如果結合在一起,就可以製造出一次重大的攻擊,因此我們應該嚴肅對待一切漏洞
2.6. 攻擊一個系統可能獲得的收益越高,人們就越有可能應用更多的技術和資源來對這個系統發起攻擊
- 2.6.1. 政府、軍方、大型企業和金融機構的系統都是重大的攻擊目標
2.7. 與一切形式的攻擊行為一樣,攻擊的難度總是小於抵禦攻擊的難度
-
2.7.1. 攻擊者只需要選擇好切入點,然後下定決心去利用盡可能多的漏洞就可以了,因為攻擊者其實只需要成功一次就夠了
-
2.7.2. 防守方需要善加利用所有可用的優勢
3. 4個問題
3.1. 我們的工作是什麼?
- 3.1.1. 旨在建立專案的背景和範圍
3.2. 哪裡有可能出錯?
- 3.2.1. 旨在儘可能地判斷有可能發生的問題
3.3. 我們打算怎麼辦?
- 3.3.1. 旨在設法緩解我們發現的問題
3.4. 我們幹得怎麼樣?
-
3.4.1. 旨在讓我們對整個流程發問
-
3.4.1.1. 軟體承擔了什麼工作
-
3.4.1.2. 軟體可能產生什麼問題
-
3.4.1.3. 我們在應對這些威脅的時候發揮得如何
4. 威脅建模
4.1. 哪裡有可能出錯?
- 4.1.1. 在安全領域,這個問題毫無反諷的意味,它簡潔地表達了威脅建模的出發點
4.2. 威脅建模的基本流程
-
4.2.1. 從系統模型出發,確保我們對整個系統範疇內的要求全都進行了考量
-
4.2.2. 判斷系統中需要加以保護的資產(包括有價值的資料和資源)
-
4.2.3. 逐個元件地搜尋系統模型,尋找潛在的威脅,判斷攻擊面(即攻擊的起源地)、信任邊界(連線系統可靠元件和不可靠元件的介面)以及不同型別的威脅
-
4.2.4. 按照確定性從高到低的順序,依次分析這些潛在的威脅
-
4.2.5. 按照嚴重性從高到低的順序,依次對威脅進行評分
-
4.2.6. 對最嚴重的威脅提出降低風險的緩解措施
-
4.2.7. 從效果最好、實施最簡單的方法開始,不斷增加緩解措施,直至看到實際的效果
-
4.2.8. 從最關鍵的威脅開始,逐個測試緩解措施的效果
4.3. 在實踐當中,第一次威脅建模只應該關注那些針對高價值資產的重大、高風險威脅
4.4. 人們在日常生活中都會根據本能,做一些類似於威脅建模的工作,採取符合一般常識的預防性措施
- 4.4.1. 在別人能聽到的地方說話就是攻擊面,用無聲的輸入法代替語言表達就是一種行之有效的緩解措施
4.5. 雖然我們在現實生活中會自然而然地採取這樣的行動,但是把這些方法應用到我們本能還不能覆蓋的複雜軟體系統上則需要制定更多的規則
4.6. 威脅建模會使用資料流圖(Data Flow Diagram,DFD)或者統一建模語言(Unified Modeling Language,UML)
- 4.6.1. 更加正式的方法往往更加嚴格,輸出的結果也更加準確
4.7. 比較理想的軟體可以把工作中最重要的內容全部自動化
- 4.7.1. 解釋輸出的結果並且進行風險評估還是需要人工介入
4.8. 按照Goldilocks原則選擇合適的粒度
-
4.8.1. 不要摻雜過多的細節(否則工作永遠也做不完)
-
4.8.2. 不要太過提綱挈領(否則我們會忽略很多重要的細節)
-
4.8.3. 如果這項工作很快就完成了,但我們還是沒有獲得針對目標系統的太多資訊,這就很可能表示粒度不夠
-
4.8.4. 如果我們埋頭苦幹了幾個小時之後,發現距離成果還有十萬八千里,就說明粒度有些過高了
5. 判斷資產
5.1. 資產是指系統中我們必須加以保護的實體
-
5.1.1. 大多數資產都是資料,但是資產也有可能包含硬體、通訊頻寬、計算資源和其他物理資源(如電能等)等
-
5.1.2. 威脅建模的初學者一般都希望對所有資產統統加以保護
-
5.1.3. 在實際工作中,我們需要對自己的資產進行優先順序排序
-
5.1.4. 應該始終確保內部系統日誌是保密的
-
5.1.4.1. 讓管理員成為唯一可以讀取日誌內容的賬戶
-
5.1.5. 應該保證將有限的精力優先投入到需要加以保護的資產上
5.2. 建議不要試著去做複雜的風險評估計算
5.3. 對資產進行優先順序排序其實有一種簡單而且非常高效的方式,那就是透過“襯衫尺碼”來對它們進行排序
-
5.3.1. 需要進行優先順序排序的資產應該包含客戶資源、個人資訊、企業文件、操作日誌和軟體程式碼等,當然這些只是一部分高優先順序資產
-
5.3.2. 不同資料洩露、篡改和破壞帶來的負面影響也大不相同
5.4. 如果我們把資產集中起來,就可以大幅簡化我們的分析工作,不過我們也要注意在這個過程中不能錯失重要的資訊
5.5. 一定要從各方的角度分別考慮資產的價值
-
5.5.1. 資產中每一項的價值都取決於你在這家公司扮演的角色是CEO、廣告人員、客戶,還是希望從網路攻擊中攫取經濟利益或者政治回報的駭客
-
5.5.2. 即使是客戶,不同的客戶對通訊中的資料隱私和資料價值也有不同的理解
-
5.5.3. 優秀的資料管理原則規定,對客戶和合作夥伴的資料所提供的保護應該超過對自己企業資料提供的保護
6. 判斷攻擊面
6.1. 我們應該考慮盡一切可能縮小攻擊面,因為這樣可以徹底消弭潛在的攻擊源
6.2. 很多攻擊都有可能在整個系統中散佈出去,所以儘早防禦這類攻擊才是最好的防禦方式
- 6.2.1. 安全的政府大樓都會把配備金屬探測器的檢驗裝置放在大樓唯一的公共入口處
6.3. 軟體設計往往比設計一棟物理大樓要複雜得多,所以判斷整個攻擊面也殊非易事
6.4. 應該把內部網路看成一個風險比較小的攻擊面
6.5. 攻擊面不侷限於數字世界內部
- 6.5.1. 攻擊者甚至可以執行側通道攻擊(side-channel attack),即透過檢測系統發出的電磁訊號、熱量、功耗甚至鍵盤的聲音等資訊,來推測系統內部的狀態
7. 判斷信任邊界
7.1. 信任和許可權總是相互關聯的,所以我們也可以把信任邊界理解為許可權邊界
- 7.1.1. 信任和許可權是高度相關的:只要信任度夠高,許可權往往也就很高,反之亦然
7.2. 如果在人類社會中給信任邊界進行類比,那麼信任邊界可以類比公司經理(瞭解更多內部資訊)和員工之間的資訊差,或者你家的大門(你可以選擇誰能夠進入你的家門)
7.3. 作業系統的核心-使用者介面就是信任邊界的經典示例
-
7.3.1. 系統會啟動核心
-
7.3.2. 核心會把應用隔離在不同的使用者處理例項當中
-
7.3.2.1. 不同的使用者處理例項對應不同的使用者賬戶
-
7.3.3. 這樣就可以避免各個使用者相互干擾,或者整個系統徹底崩潰
7.4. 安全外殼(Secure Shell,SSH)守護程序(sshd)是一個理想的、採用了信任邊界的安全設計示例
-
7.4.1. 為了能夠接收SSH登入請求,守護程序必須為通訊建立一條安全的通道(在這條通道中傳輸的資料不會被嗅探或者篡改),然後才能處理和驗證敏感的證書
-
7.4.2. 需要呼叫大量程式碼、使用最高的優先順序執行程式(這樣才能為所有使用者賬戶建立程序)
-
7.4.3. 入站的請求可以來自網際網路的任何一個角落,而請求是否是攻擊行為一開始根本無從判斷,所以我們很難找到更有吸引力的目標
7.5. 在一個作業系統中,超級使用者固然應該擁有最高階別的信任,其他管理員使用者也可以考慮獲得類似級別的許可權
- 7.5.1. 訪客賬戶的信任級別一般都是最低的,而且我們可能更需要針對這類使用者來保護我們的系統,而不是去保護這類使用者的資源
7.6. Web伺服器需要有能力抵禦惡意客戶端使用者,因此Web前端系統往往會對入站的流量進行驗證,並且只轉發那些合法的請求,這就有效地建立起了與網際網路之間的信任邊界
7.7. 在信任邊界的兩邊,一定要透過定義明確的介面和協議來提供轉換和過渡
7.8. 最大的風險往往隱藏在從低信任區域向高信任區域過渡的地方
-
7.8.1. 不代表我們就可以忽視那些從高信任區域向低信任區域過渡的場景
-
7.8.2. 只要我們的系統還在向那些信任度比較低的元件傳送資料,我們就應該考慮資訊洩露的可能性和出現其他問題的可能性
-
7.8.3. 不要用敏感的資訊來命名計算機,這樣會讓攻擊者得到重要的提示,從而有機會在系統上執行程式碼來對系統實施入侵
-
7.8.4. 只要高信任服務會代表低信任請求來運作,這個系統就有遭到DoS攻擊的風險
-
7.8.4.1. 使用者請求方可能會透過這種方式讓系統核心過載
8. 判斷威脅
8.1. 威脅往往會集中在重要資產和信任邊界周圍,但是也有可能出現在系統的任何一個地方
8.2. 系統的主要威脅會集中於我們的資產和系統的信任邊界
8.3. 即使很小的威脅也有可能需要我們採取措施進行緩解
- 8.3.1. 是否需要採取措施取決於這些威脅有多大的可能性會發展成嚴重的問題,以及它所針對的資產有多高的價值
8.4. STRIDE關注的重點是判斷威脅的過程
- 8.4.1. STRIDE只是對軟體面臨的威脅進行了分類
8.5. STRIDE中有一半的威脅屬於對基礎資訊保安的直接威脅
-
8.5.1. 資訊洩露針對的是機密性
-
8.5.2. 篡改針對的是完整性
-
8.5.3. 拒絕服務則旨在破壞資訊的可用性
8.6. STRIDE的另一半針對的是黃金標準
-
8.6.1. 欺騙是透過建立虛假的身份來破壞真實性
-
8.6.2. 許可權提升破壞的是正確的授權
-
8.6.3. 抵賴則是對審計的威脅
-
8.6.3.1. 避免抵賴這種威脅的方法是讓管理員和使用者明白,他們都要對自己的行為負責
-
8.6.3.2. 他們都知道系統中有一份準確的審計記錄
9. 緩解威脅
9.1. 透過重新設計或者增加防禦的方式來緩解威脅,從而減少威脅的發生,或者把威脅造成的傷害降到可以接受的程度
9.2. 如果受到威脅的資產不是必要的資訊,就直接把這些資訊刪除
- 9.2.1. 如果不可能刪除這些資訊,就努力降低這些資訊暴露的可能性,或者對可能增加威脅性的可選特性進行限制
9.3. 把一些責任交給第三方,從而轉移風險
9.4. 在充分理解風險之後,接受風險的存在,承認風險的發生自有其合理性
9.5. 部分緩解措施
-
9.5.1. 降低傷害發生的機率:讓攻擊只可能在一小段時間內發生
-
9.5.2. 降低傷害的嚴重程度:讓攻擊只能破壞一小部分資料
-
9.5.3. 設法逆轉傷害:確保我們可以從備份檔案中輕鬆恢復所有丟失的資料
-
9.5.4. 設計傷害正在發生的訊號:使用防篡改的包裝,當產品遭到篡改的時候能夠輕鬆發現篡改已經發生,從而對消費者提供保護
-
9.5.4.1. 在軟體領域,良好的日誌記錄可以起到這樣的效果
10. 隱私方面
10.1. 針對隱私的威脅手段與其他安全威脅手段一樣真實
-
10.1.1. 在對系統面臨的威脅進行完整的評估時,這些針對隱私構成威脅的方式需要進行單獨的分析
-
10.1.2. 這類威脅在資訊洩露的風險中增加了人為因素
10.2. 我們應該把自己看成個人資訊的管家,努力從使用者的角度進行考慮,包括認真考慮使用者關注的隱私安全問題,並且為了避免使用者隱私洩露,怎麼關注都不為過
10.3. 隨著人們的生活日趨數字化,移動計算裝置已經無處不在,隱私也越來越依賴這些程式碼,未來如何發展殊難預料
- 10.3.1. 最明智的做法是保持高度警惕,並且始終站在時代浪潮的潮頭
10.4. 降低隱私威脅的一般解決方案
-
10.4.1. 對真實的使用者案例進行建模,然後對隱私進行評估,而不要僅思考抽象的內容
-
10.4.2. 學習所應用的隱私策略或法規,然後嚴格遵守這些條款
-
10.4.3. 透過限制手段,保證只有在必要的情況下才收集資料
-
10.4.4. 對看起來後果非常嚴重的威脅保持警惕
-
10.4.5. 不要在沒有清晰使用意圖的情況下收集或者儲存隱私資訊
-
10.4.6. 當收集到的資訊不需要繼續使用的時候,要主動刪除這些資訊
-
10.4.7. 減少敏感資訊的洩露
-
10.4.7.1. 在理想情況下,敏感資訊只能分享給需要知道的人
-
10.4.8. 減少與第三方共享的資訊
-
10.4.8.1. 如果存在這類資訊,應該用文件進行詳細的記錄
-
10.4.9. 要保持透明,讓終端使用者理解自己的資料保護措施