讀軟體開發安全之道:概念、設計與實施15安全測試

躺柒發表於2024-09-02

1. 安全測試

1.1. 測試是開發可靠、安全程式碼中的關鍵一環

1.2. 測試安全漏洞的目的是主動檢測

1.3. 模糊測試是一種強大的補充技術,可以幫助我們找到更深層次的問題

1.4. 針對當前漏洞建立的安全迴歸測試,目的是確保我們不會再犯相同的錯誤

1.5. 大多數測試都是由執行程式碼組成的,其目的是校驗軟體是否能夠按照設計目的工作

1.6. 安全測試則正好相反,其目的是保證不允許執行的操作無法執行

  • 1.6.1. 安全測試必不可少,因為安全測試可以確保緩解措施發揮了應有的作用

  • 1.6.2. 編寫程式碼的人只專注於讓目標功能在常規使用場景中能夠正常工作,而那些出乎意料的攻擊則很難進行預測

  • 1.6.3. 安全測試可以預期到這類情況並且確保程式碼擁有必要的保護機制,從而提升程式碼的安全性

  • 1.6.4. 對於那些安全性至關重要的程式碼,推薦對它們進行徹底的安全測試,以確保程式碼的質量儘可能高

  • 1.6.5. 安全測試恐怕是我們能夠迅速提升應用安全的最理想方式,而且執行安全測試一點也不困難

  • 1.6.6. 在軟體行業,並沒有任何公開資料可以反映安全測試的普及程度,但是從相同漏洞總是反覆出現這一點來看,安全測試顯然沒有得到足夠的重視

1.7. 整數溢位

  • 1.7.1. 建立允許值的範圍,同時確保檢測並拒絕超出這個範圍的值

1.8. 記憶體管理問題

  • 1.8.1. 測試程式碼是否正確處理了超大的資料值,並且在資料值太大時拒絕這個值

1.9. 不可靠輸入

  • 1.9.1. 測試各類無效輸入資訊,以確保這些數值要麼被拒絕,要麼被轉換為能夠安全處理的有效輸入形式

1.10. Web安全

1.11. 異常處理缺陷

  • 1.11.1. 強制程式碼透過各類異常處理路徑來檢查其是否能合理地恢復

1.12. 它們都偏離了程式碼正常使用的範圍,因此這些用法都很容易被人們忽視

1.13. 所有這些攻擊方法都已經非常成熟,所以進行徹底的測試一定會產生明顯的效果

2. 功能測試

2.1. 功能測試的目的是驗證程式碼是否按照人們預期的方式執行

2.2. 更加徹底的功能測試還可能包含一些其他的測試用例

  • 2.2.1. 對失敗的校驗(即非0的返回碼)進行檢查

3. 安全測試的限制

3.1. 安全測試的目標是在程式碼中檢測出失敗的潛在主要原因,但安全測試無法涵蓋程式碼出錯的所有情形

3.2. 有可能出現一類漏洞正好是我們編寫的測試無法檢測出來的,不過這種情況在不經意間出現的機率不高

3.3. 除非測試覆蓋的範圍非常完整,否則還是有可能存在透過編寫bug來躲避測試的

3.4. 原則

  • 3.4.1. 安全測試對那些強調安全性的程式碼來說尤為重要

  • 3.4.2. 最重要的安全測試往往會對某些行為進行校驗

  • 3.4.2.1. 如拒絕訪問、拒絕輸入或者執行失敗(而不是成功)​

  • 3.4.3. 安全測試用例應該確保每一個關鍵步驟都能正確執行

4. 安全測試用例

4.1. 安全測試用例可以確保某一種特定的安全失敗不會發生

4.2. 滲透測試是指好人在軟體中尋找漏洞,其目的是在壞人發現漏洞之前對其進行修復,滲透測試不會嘗試找出所有可能的漏洞

4.3. 安全測試也和滲透測試有所不同,因為安全測試還會對被發現的漏洞提供保護

4.4. 安全測試用例會校驗主動機制是否正常工作,因此往往會涉及對無效輸入和不允許執行的操作的拒絕

4.5. 應該在編寫其他單元測試的時候建立安全測試用例,而不是在發現漏洞的時候才撰寫安全測試用例

4.6. 安全系統會透過阻塞不合理的行為、拒絕惡意的輸入、拒絕訪問等方式來對寶貴的資源進行保護

  • 4.6.1. 只要存在這類安全機制,我們就應該建立安全測試用例來確保那些未經授權的操作一定會以失敗告終

4.7. 常見的安全測試用例包括測試使用錯誤密碼登入的嘗試失敗、從使用者空間對核心資源發起未經授權的嘗試失敗,以及無效或偽造的數字證書永遠都會被拒絕

4.8. 閱讀程式碼是編寫優質安全測試用例的理想方法

4.9. 測試輸入驗證

4.10. 測試XSS漏洞

5. 模糊測試

5.1. 模糊測試是一種自動建立測試用例的方式,其目的是透過測試輸入來“轟炸”目的碼

5.2. 模糊測試可以幫助我們判斷某個輸入是否有可能導致程式碼出現問題,或者導致流程崩潰

5.3. 模糊測試這種分散的方法也可以相當有效地發現更大範圍的錯誤,其中一些錯誤就是軟體的漏洞,在這一點上,模糊測試完全不同於為特定目的而編寫的安全測試

5.4. 典型的方法是“模糊”那些不可靠的輸入(即嘗試各種不同的值)​,然後查詢異常的結果或者崩潰的情形

5.5. 很多庫都提供了各式各樣的模糊功能,從隨機模糊到基於特定格式(如 HTML、XML 和JSON)的知識所生成的變體

6. 安全迴歸測試

6.1. 安全漏洞一經發現和修復,就沒人希望再被相同的漏洞襲擾

6.2. 在對新發現的安全漏洞進行響應時,有一項重要的最佳實踐,那就是建立一個安全迴歸測試來檢測潛在的錯誤

6.3. 安全迴歸測試的作用是對漏洞進行簡單重現(重現錯誤)​,以確認我們的修復工作在事實上消除了漏洞

6.4. 一些安全漏洞迴歸的情況比新的漏洞還要糟糕得多

  • 6.4.1. 蘋果在2019年釋出iOS 12.4的時候,這個版本重新引入了在iOS 12.3中已經發現並且修復的錯誤,這無異於推開了一扇本應該已經牢牢關閉的大門

6.5. 一個理想的安全迴歸測試應該嘗試多種測試用例,而不是針對某一種已知攻擊建立測試用例

6.6. 除了解決新發現的漏洞之外,透過調查也可能會在系統的其他地方發現類似漏洞,這些漏洞同樣可以被攻擊者利用

  • 6.6.1. 我們可以利用自己對系統內部的瞭解和對原始碼的熟悉,在同對手的競爭中佔據先機

  • 6.6.2. 攻擊者很可能也是按照相同的思路來思考,而釋出修復程式無異於是在給攻擊者提供如何攻擊自己的系統的線索

7. 可用性測試

7.1. DoS攻擊表示一種特殊型別的威脅,因為系統能夠承受的負載上限是很難加以歸類的

7.2. 負載(load)這個詞包含多重含義,包括處理能力、記憶體佔用、作業系統資源、網路頻寬、磁碟容量以及其他可能存在的瓶頸

7.3. 安全測試還可以避免故意利用效能漏洞的攻擊方式

7.4. 安全測試應該有能力判斷出效能有可能呈非線性下降的程式碼

7.5. 資源消耗

  • 7.5.1. 對於那些我們深知有可能受到可用性攻擊威脅的功能,我們應該增加安全測試用例(對資源)​,並且確定輸入的合理限制以防止負載過高

  • 7.5.2. 一種簡單的方法可以防止程式碼變更導致記憶體消耗急劇增加,那就是人為製造資源受限的條件並允許測試

  • 7.5.3. 單元測試應該在記憶體非常受限的條件下執行

  • 7.5.4. 更大規模的整合測試則要求測試時使用的資源與生產中的可用資源相仿,如果使用與生產中幾乎完全相同的資源來執行測試,測試就可以起到警示作用

7.6. 冒煙測試、負載測試和相容性測試

7.7. 閾值測試

  • 7.7.1. 一種保護系統可用性的重要方式很容易被人們忽視,那就是在達到基本限制之前建立一個警告標誌

  • 7.7.1.1. 如果對計數器值進行監測並且在數值接近上限(如0.99*INT_MAX)時發出警告,災難原本可以避免

  • 7.7.2. 對閾值進行告警的工作往往被看作運維人員的職責,而不是安全測試團隊的工作

  • 7.7.3. 儲存容量是另一個我們希望獲得預先告警的重要資料

  • 7.7.3.1. 針對儲存容量,我們可以把告警值設定為限制值的99%,而不是某個任意的閾值

  • 7.7.3.2. 一種更加有用的計算方法是計算一個時間序列(也就是儲存容量隨時間變化的一組測量值)​,並且推斷到達限制值所需的時間

  • 7.7.4. 時間限制也絕對不能忽視

  • 7.7.4.1. 數字證書的過期時間很容易被人們忽視

7.8. 分散式拒絕服務攻擊

  • 7.8.1. 拒絕服務(Denial of Service,DoS)攻擊是一種單獨的行為,旨在給可用性造成負面影響

  • 7.8.2. 分散式拒絕服務(Distributed Denial of Service,DDoS)攻擊則透過多項協同行為的累積效應來完成攻擊

相關文章