Share via


建置可靠且安全的 C++ 程式

美國 政府出版物 NISTIR 8397:軟體開發人員驗證最低標準指導方針包含如何以任何程式設計語言建置可靠且安全的軟體的絕佳指引。

本檔遵循與 NISTIR 8397 相同的結構。 每個區段:

  • 摘要說明如何使用適用於 C++ 和其他語言的 Microsoft 開發人員產品來滿足該區段的安全性需求,以及
  • 提供取得每個區域中最多值的指引。

2.1 威脅模型

摘要

威脅模型化是一個有價值的程式,特別是在以符合您的開發需求和降低雜訊的方式套用時。

建議

威脅模型應該是動態安全性開發生命週期 (SDL) 的一部分。 建議您針對整體產品、特定功能,或主要設計或實作變更:

  • 擁有穩固且動態的 SDL,可讓您與開發人員小組進行早期接觸,並讓方法獲得權利。
  • 以目標方式套用威脅模型化。 將威脅模型化套用至所有功能,但從戰術上開始於公開、複雜或關鍵功能。 請定期套用它,做為自上而下的產品檢閱的一部分。
  • 儘早套用威脅模型化(如同所有安全性需求),當仍有機會變更設計時。 此外,威脅模型可作為其他進程的輸入,例如攻擊面縮小或設計安全性。 稍後建立的威脅模型最適合「調查」筆測試(滲透測試)或需要安全性測試的區域,例如模糊。 建立基準威脅模型之後,請規劃在受攻擊面變更時繼續逐一查看。
  • 使用資產清查和合規性來適當追蹤組成產品的內容,以及追蹤安全性成品(包括威脅模型),以及其適用的資產。 此方法可讓您更妥善地進行自動化風險評估,並將安全性工作聚焦於變更的特定元件或功能。
  • 在 Azure 中,Microsoft Threat Modeling Tool 已於 2022 年更新為 Azure 開發。 如需詳細資訊,請參閱 Microsoft 威脅模型化工具概觀 - Azure

支援因素和做法

若要正確套用威脅模型化並避免過度使用,我們發現必須先解決下列核心概念。

開發方法

首先,瞭解小組的開發方法。 對於每天將數十項變更推送至生產環境的敏捷式開發工作流程的小組,對於每個功能變更都需要威脅模型更新並不實用或合理。 相反地,從撰寫功能的功能需求開始,請考慮包括安全性需求問卷。 問卷應著重於功能的特定問題,以判斷 SDL 的未來層面。 例如:

  • 此功能在設計時是否對如何在多租用戶環境中提供客戶隔離做出重大變更? 如果是,請考慮執行完整的威脅模型。
  • 新功能是否允許檔案上傳? 如果是的話,也許更合適的是 Web 應用程式安全性評估。
  • 這項變更主要是功能 UI 變更嗎? 如果是的話,也許除了傳統的自動化工具之外,不需要任何專案。

安全性問卷結果會告知哪些 SDL 技術要與哪一個開發單位系結。 它也會通知開發合作夥伴此功能的 SDL 時程表,讓他們可以在正確的時間共同作業。

產品庫存

其次,針對您負責評估的產品,維護強大的資產清查。 產品在複雜度上越來越高。 針對已連線的裝置撰寫軟體很常見::

  • 感測器(如客運鐵路和車輛)
  • 與車輛中其他元件通訊的總線型網路(例如 CANBUS 或 PROFIBUS),
  • 無線/行動數據/藍牙,可與客戶裝置和雲端後端通訊,
  • 雲端中的機器學習服務會送回裝置或車隊管理應用程式,
  • 等等。

在這類複雜的產品中,威脅模型化非常重要。 擁有強大的資產清查可讓您檢視整個產品堆疊,以查看完整圖片,以及查看需要評估新功能或變更功能如何影響產品安全性的重要位置。

數據粒度和整合

建立系統,以使用明確的計量來測量合規性。

  • 定期測量功能層級開發的合規性。 功能合規性通常應該以較高的頻率和較小的粒度來測量,有時甚至是在開發人員的系統上,或在程式碼認可/合併時間進行測量。
  • 定期評估取用功能或元件之更廣泛產品的安全性。 更廣泛的評估通常會以較低的頻率和更廣泛的粒度來完成,例如在模組或系統測試時間。

縮放比例

保留適當的資產清查系統,以擷取並保留安全性成品,以及威脅模型檢閱的輸出。 清查清楚可讓您評估模式的檢閱輸出,並針對如何定期精簡產品安全性計劃做出明智的決策。

嘗試結合需求階段安全性問卷、威脅模型化結果、安全性評估結果,以及自動化工具的結果。 結合它們可讓您將特定產品的相對風險觀點自動化,在理想情況下為「儀錶板」,以通知安全性小組要專注於什麼,以充分利用威脅模型化的最佳價值。

2.2 自動化測試

摘要

自動化測試是確保程式代碼品質和安全性的重要方式。 它們是支援本檔中提及的其他區域不可或缺的一部分,例如威脅模型化。 與其他安全程式代碼撰寫做法配對時,它們有助於防範程式代碼基底中導入的 Bug 和弱點。

索引鍵屬性

測試應該是可靠、一致且隔離的。 這些測試應該盡可能涵蓋大部分的程序代碼。 所有新功能和錯誤修正都應該有對應的測試,以確保盡可能確保程式碼的長期安全性和可靠性。 定期執行自動化測試,並在盡可能多的環境中執行,以確保它們能執行,並涵蓋所有領域:

  • 他們應該執行的第一個位置是在進行變更的計算機上。 執行測試最容易在用於編輯的 IDE 內完成,或當開發人員進行變更時,在命令行上做為腳本。
  • 其應該執行的下一個位置是提取要求認可/合併程式的一部分。
  • 執行測試的最後一個位置是持續整合和持續部署 (CI/CD) 管線的一部分,或作為發行候選組建的一部分。

測試的範圍應該在每個步驟增加,最後一個步驟會提供其他步驟可能遺漏的任何完整涵蓋範圍。

持續使用和維護

測試可靠性是維護測試套件有效性的重要部分。 測試失敗應該指派和調查,潛在的安全性問題會優先於高優先順序,並在提示和預先決定的時間範圍內更新。 忽略測試失敗不應該是常見的作法,但應該需要強有力的理由和核准。 測試失敗是因為測試套件本身內的問題應該與其他失敗相同,以避免遺漏產品問題的涵蓋範圍失敗。

測試種類,特別是單元測試

有數種類型的自動化測試,雖然並非所有應用程式都適用,但良好的測試套件包含數種不同類型的選擇。 以程式代碼為基礎的測試案例,例如單元測試是最常見且最不可或缺的,適用於所有應用程式,並刻意涵蓋盡可能多的程式碼路徑,以取得正確性。 這些測試應該很小、快速且不會影響機器的狀態,以便快速且經常地執行完整的測試套件。 可能的話,請在具有不同硬體設定的許多計算機上執行測試,以攔截單一計算機上無法重現的問題。

Visual Studio

Visual Studio 測試總管原生支援許多最熱門的 C++ 測試架構,並有選項可安裝延伸模組以取得更多架構。 這項彈性有助於執行涵蓋您所處理程式碼的測試子集,並讓您在測試失敗發生時輕鬆偵錯。 Visual Studio 也可讓您輕鬆地為現有項目設定新的測試套件,並提供實用的工具,例如 CodeLens,讓您更輕鬆地管理這些測試。 如需使用 Visual Studio 撰寫、執行和管理 C/C++ 測試的詳細資訊,請參閱 撰寫 C/C++ 的單元測試 - Visual Studio (Windows)

在 Azure 和 GitHub CI/CD 中

執行更深入驗證且需要較長時間才能執行的測試,例如靜態分析、元件偵測等等,是提取要求測試或持續整合測試的良好候選專案。 Azure DevOps 和 GitHub Actions 可讓您輕鬆地在驗證失敗時自動執行驗證,並封鎖程式代碼簽核。 自動化強制執行有助於確保所有正在簽入的程式代碼都是安全的,這些更嚴格的檢查正在執行。 以下說明 Azure Pipelines 和 Azure DevOps 組建驗證:

2.3 程式代碼型或靜態分析

摘要 預設應啟用靜態程序代碼/二進位分析,預設為安全。 靜態分析會分析程式在建置時所需的安全策略,而不是在客戶計算機上可能發生惡意探索的運行時間。 靜態分析可以在原始程式碼表單或已編譯的可執行表單中分析程式。

建議 Microsoft 建議您:

  • 針對所有 C++ 程式啟用靜態分析,包括輸入原始碼(編譯之前)和可執行二進位檔(編譯之後)。 「啟用」可能表示在開發人員計算機上每個組建期間執行分析,或做為個別組建,以稍後檢查程式代碼或簽入需求。
  • 將靜態分析併入 CI 管線作為測試形式。
  • 依定義的靜態分析隨附誤判,並準備好將該事實納入您的品質意見反應迴圈。 快速啟用所有正面低誤判警告。 然後主動增加程式代碼基底編譯警告清除的規則數目,因為您經常新增更多規則,以犧牲逐漸較高的誤判為代價來標幟重要 Bug(一開始,在程式代碼基底也清除這些規則之前)。
  • 請一律使用最新支援的 Visual Studio 版本,並設定您的工程環境,以在有最新修補程式版本可用時快速取用最新的修補程式版本,而不會延遲到下一個開發階段/週期。

重要工具 請注意並使用下列專案:

注意:

  • /analyze 可在編譯階段對 C++ 程式代碼進行靜態分析,以識別重要的安全性和可靠性程式碼弱點。 它應該在整個 C++ 程式的整個開發時間軸上啟用。 從預設至少啟用「Microsoft Native Recommended」作為最低基準開始。 然後,請參閱檔,以瞭解如何指定更多規則,特別是您的工程原則所需的 C++ 核心指導方針規則。 原始碼靜態分析功能可在 Visual C++ IDE 和命令行建置工具中使用。
  • /W4 應盡可能啟用 和 /WX ,以確保您在高警告層級 (W4) 完全編譯程式代碼,並將警告視為必須修正的錯誤(WX)。 這些選項可讓您尋找其他靜態分析工具無法檢查的非初始化數據錯誤,因為只有在編譯程式後端執行程式間分析和內嵌之後,才會顯示錯誤。
  • BinSkim 二進位分析可確保專案能夠啟用廣泛的安全性功能。 BinSkim 會產生 PDB 和其他輸出,讓您更輕鬆地驗證監管鏈,並有效率地回應安全性問題。 Microsoft 建議執行 BinSkim 工具,分析程式針對或取用的所有可執行二進位檔 (.sys.dll.exe) 。 BinSkim 使用者指南包含支援的安全性標準清單。 Microsoft 建議您修正 BinSkim 工具回報為「錯誤」的所有問題。 回報為「警告」的問題應該有選擇性地評估,因為解決這些問題可能會對效能造成影響,或可能沒有必要。

在 Azure 和 GitHub CI/CD 中,Microsoft 建議一律在發行 CI/CD 案例中啟用原始程式碼和二進位靜態分析。 立即在本機開發人員的計算機上執行來源分析,或至少針對每個認可或提取要求執行來源錯誤,以儘早攔截來源錯誤,並將整體成本降至最低。 二進位層級錯誤通常較慢地引入,因此在較不頻繁的發行前版本 CI/CD 案例中執行二進位分析可能就已足夠(例如夜間或每周組建)。

2.4 針對硬式編碼秘密進行檢閱

摘要

請勿在軟體內硬式編碼秘密。 您可以使用可掃描整個原始程式碼基底的可靠工具,有效率地尋找並移除原始碼中的秘密。 找到秘密之後,請遵循安全儲存和使用秘密的指導方針,將它們移至安全的地方。

問題

「秘密」表示建立身分識別並提供資源的存取權,或用來簽署或加密敏感數據的實體。 範例包括密碼、記憶體金鑰、連接字串 和私鑰。 在軟體產品中保留秘密很誘人,因此軟體可在需要時隨時取得這些秘密。 不過,這些硬式編碼的秘密可能會導致嚴重或災難性的安全性事件,因為它們很容易被發現,而且可用來危害您的服務和數據。

預防

原始碼中硬式編碼的秘密(純文字或加密的 Blob)是安全性弱點。 以下是如何避免原始程式碼中秘密的一般指導方針:

  • 在提交原始檔控制之前,使用預先檢查工具來掃描並攔截程式代碼中潛在的硬式編碼秘密。
  • 請勿在原始程式碼或組態檔中放入純文本認證。
  • 請勿將純文本認證儲存在 SharePoint、OneNote、檔案共用等等。 或透過電子郵件、IM等方式共享它們。
  • 請勿使用容易探索到的解密金鑰來加密秘密。 例如,請勿儲存 PFX 檔案以及包含其密碼的檔案。
  • 請勿使用弱式解密來加密秘密。 例如,請勿使用弱式或通用密碼加密 PFX 檔案。
  • 避免將加密的認證放在原始程式碼中。 請改用來源中的佔位元,讓您的部署系統以核准存放區中的秘密取代它們。
  • 在測試、預備等環境中將相同的原則套用至秘密,就像您在生產部署中所做的一樣。 敵人通常會以非生產系統為目標,因為它們管理得不太好,然後使用它們來轉向生產環境。
  • 請勿在部署之間共用秘密(例如測試、預備、生產環境)。

雖然與硬式編碼的秘密不直接相關,但也記得保護測試、開發和生產環境的秘密:

  • 定期輪替您的秘密,以及每當可能公開秘密時。 證明輪替/重新部署秘密的能力是安全系統的證據。 更值得注意的是,缺乏這項能力甚至更強烈地證明瞭不可避免的弱點。
  • 請勿屈從於「我的測試認證不會造成風險」的常見開發人員理由。實際上,他們幾乎總是這樣做。
  • 請考慮完全偏離秘密(例如密碼、持有人密鑰),完全偏好使用 RBAC/identity-driven 解決方案作為良好的工程解決方案,以避開秘密管理不善。

偵測

您產品的舊版元件可能包含原始碼中隱藏的硬式編碼秘密。 有時候開發人員桌面計算機的秘密可以爬進遠端分支,並合併到發行分支,無意中洩漏秘密。 若要探索可能隱藏在原始程式碼中的秘密,您可以使用可掃描程式代碼中的硬式編碼秘密的工具:

補救

當您的原始程式碼中找到認證時,立即需要使公開的密鑰失效,並根據暴露情況執行風險分析。 即使您的系統需要持續執行,您也可以使用下列步驟啟用秘密管理員以進行補救:

  1. 如果補救允許切換至受控識別,或需要卸除秘密管理員,例如 Azure 金鑰保存庫 (AKV),請先這麼做。 然後使用更新的身分識別或金鑰重新部署。
  2. 使公開的秘密失效。
  3. 執行稽核/風險評估,以評估因入侵所造成的潛在損害。

若要保護雲端應用程式和服務所使用的密碼編譯密鑰和其他秘密,請使用 Azure 金鑰保存庫 搭配適當的存取原則。

如果曝光危害特定客戶數據/PII,可能需要其他合規性/報告需求。

從原始碼中移除現在無效的秘密,並將其取代為不會直接在原始程式碼中公開秘密的替代方法。 尋找使用 Azure AD 之類的工具,盡可能消除秘密的機會。 您可以更新驗證方法,以透過 Azure Active Directory 利用受控識別。 僅使用核准的存放區來儲存和管理秘密,例如 Azure 金鑰保存庫 (AKV)。 如需詳細資訊,請參閱

Azure DevOps (AzDO)

AzDO 使用者可以透過適用於 Azure DevOps 的 GitHub 進階安全性來掃描其程式代碼(GHAzDO)。 GHAzDO 也可讓使用者在存放庫上啟用推播保護來防止秘密暴露,並攔截潛在暴露,再洩漏。 如需如何在 Azure DevOps 中偵測程式代碼中硬式編碼秘密的詳細資訊,請參閱下列每個連結中的 Github 進階安全性秘密掃描:

在 GitHub 中

秘密掃描可在兩種形式 GitHub.com 上取得:

  • 合作夥伴的秘密掃描警示。 在所有公用存放庫上自動執行。 任何符合秘密掃描夥伴所提供模式的字串,會直接回報給相關合作夥伴。
  • 使用者的秘密掃描警示。 您可以針對使用 GitHub Enterprise Cloud 且具有 GitHub 進階安全性授權的組織所擁有的存放庫啟用和設定額外的掃描。 這些工具也支援私人和內部存放庫。

GitHub 為合作夥伴和使用者可以提供已知的秘密模式,這些模式可設定為符合您的需求。 如需詳細資訊,請參閱:

注意

適用於 Azure DevOps 的 GitHub 進階安全性帶來了相同的秘密掃描、相依性掃描和 CodeQL 程式代碼掃描解決方案,這些解決方案已可供 GitHub 使用者使用,並原生地將它們整合到 Azure DevOps 中,以保護您的 Azure Repos 和 Pipelines。

其他資源

2.5 使用語言和操作系統提供的檢查和保護來執行

摘要

二進位強化是藉由套用編譯時間安全性控件來完成。 這些包括下列風險降低:

  • 防止程式代碼中可惡意探索的弱點,
  • 啟用在惡意探索上觸發安全性防禦的運行時間偵測,以及
  • 讓數據生產和封存能夠協助限制安全性事件所造成的損害。

二進位取用者必須選擇加入 Windows 安全性功能,以取得強化的完整優點。

Microsoft 提供 C++ 專案專屬的一組設施,可協助開發人員撰寫及交付更安全且更安全的程式碼。 C++ 開發人員也應該遵守產生可執行程式碼之語言通用的安全性標準。 Microsoft 維護 BinSkim,這是公用 OSS 二進制檢查程式,可協助強制執行本節中所述的許多保護。 如需 BinSkim 的詳細資訊,請參閱 Binskim 使用者指南 |GitHub

二元層級控件會根據在工程程式中套用的位置而有所不同。 您應該區分編譯程式和連結器選項:嚴格編譯時間、改變程式代碼產生與運行時間額外負荷,以及改變程式代碼產生,以達到與 OS 保護的相容性。

開發人員設定應該偏好儘可能啟用靜態分析、啟用私人數據生產以加速偵錯等等。 發行組建應該調整為適當的安全性、效能和其他程式代碼產生考慮的組合。 發行程式必須設定為正確產生及管理公用與私用的建置數據(例如,公用與私人符號)。

保持最新狀態:一律使用最新的編譯程式和工具

使用目前的工具組編譯所有程序代碼,以受益於最新的語言支援、靜態分析、程式代碼產生和安全性控制。 因為編譯程式會影響每個產生的元件,因此工具更新上回歸的可能性相對較高。 使用過時的編譯程式會在回應安全性事件時建立更正動作的特定風險,因為小組可能沒有足夠的時間來升級編譯程式。 Microsoft 建議小組開發設備,定期重新整理及測試編譯程式更新。

使用安全開發方法、語言版本、架構/API

程式代碼應利用開發方法、語言版本、架構、API 等,藉由在 C++ 中促進安全性和簡單性,以將風險降至最低,包括:

  • 請參閱 C++ 核心指導方針的指導方針支持連結庫 (GSL) ,以取得撰寫遵循最佳做法並避免常見陷阱的新式、安全且一致的 C++ 程式代碼的指引。
  • 如需 C++ 核心指導方針建議使用的函式和類型,請參閱 Microsoft GSL 實 作。
  • 資源安全的 C++ 容器、C 執行時間連結庫 (CRT) 記憶體溢位保護:偏好 std::vectorstd::string,這是資源安全。 如果您必須使用 C 數據,請使用 CRT 函式的安全版本,其設計目的是為了協助防止記憶體損毀,因為緩衝區誤用和未定義的語言行為。
  • 保管庫 Int 連結可防止數學和比較運算中的整數溢位。

取用安全相依性

二進位檔不應該連結到不安全的連結庫和相依性。 開發小組應該追蹤所有外部相依性,並在受到這些弱點時更新為更安全的版本,解決這些元件中已識別的安全性弱點。

最大化程式代碼源保證和安全性回應的效率

編譯應該啟用強式程式代碼證明保證,以協助偵測及防止引進後門程式和其他惡意代碼。 對於偵錯和調查而言,產生的數據也應該針對所有軟體版本封存,以便在遭到入侵時驅動有效率的安全性回應。 下列編譯程序參數會產生對安全性回應至關重要的資訊:

  • /ZH:SHA_SHA256 在 Visual C++ 中 - 確保使用密碼編譯安全演算法來產生所有 PDB 來源檔案哈希。
  • /Zi/ZI 、(偵錯資訊格式)在 Visual C++ 中 - 除了發佈擷取當機數據和其他公用使用案例的去除符號之外,也可確保針對所有已發行的二進位檔產生和封存私人 PDB。 二進位分析工具需要完整的符號,才能驗證編譯時期是否已啟用許多安全性防護功能。 私人符號對於安全性回應至關重要,當工程師爭先行評估並限制惡意探索時損毀時,偵錯和調查成本較低。
  • /SOURCELINK 在 Visual C++ 連結器中 - 在 PDB 中包含 Sourcelink 檔案:來源連結是語言與原始檔控制無關的系統,可提供二進位檔的來源偵錯。 來源偵錯可大幅提升發行前版本安全性驗證和發行后事件回應的範圍。

啟用編譯程式錯誤以防止程式代碼撰寫時發生問題

編譯應該啟用安全性相關的編譯程式檢查作為重大錯誤,例如:

將二進位檔標示為與OS運行時間安全性風險降低功能相容

編譯程式和連結器設定應該選擇加入程式代碼產生功能,以偵測並減輕惡意代碼執行,包括:

防止敏感性資訊洩漏

編譯程式設定應該選擇加入敏感性資訊探索防護。 近年來,研究人員發現了非預期的資訊外泄,這些洩漏源自推測性執行等硬體功能。

在軟體層級,如果意外洩漏,機密數據可能會傳送給攻擊者。 無法以零初始化緩衝區和其他緩衝區誤用,可能會將私人機密數據洩漏給呼叫受信任 API 的攻擊者。 啟用額外的靜態分析和使用安全資源容器,以達到最佳處理的問題類別,如先前所述。

  • /Qspectre - 減輕推測性執行端通道攻擊 - 插入阻礙指示,協助防止推測執行所產生的敏感數據洩漏。 針對將敏感數據儲存在記憶體中的程序代碼,並跨信任界限運作的程式代碼,應啟用這些風險降低功能。 Microsoft 一律建議您在啟用 Spectre 風險降低功能時,針對適當的效能評定測量效能影響,因為有可能在效能關鍵區塊或迴圈中引入運行時間檢查。 這些程式代碼路徑可以透過 spectre(nomitigation)declspec 修飾詞停用風險降低功能。 啟用 『/Qspectre』 的項目也應該連結到也使用這些風險降低所編譯的連結庫,包括 Microsoft 運行時間連結庫。

2.6 黑箱測試案例

摘要

黑箱測試不依賴知道測試元件的內部運作。 黑箱測試的設計目的是在任何層級或層級測試產品中功能的端對端功能。 黑箱測試可以是功能測試、UI 測試、效能測試和整合測試。 黑箱測試對於測量一般可靠性和功能正確性非常重要,並確保產品如預期般運作。

與其他區段的關聯

這些類型的需求型測試有助於驗證在威脅模型中所做的假設,並涵蓋該區段中提出的潛在威脅。 這些測試有助於測試產品的不同元件之間的整合,特別是跨信任界限的元件,如威脅模型中所述。 黑箱測試案例也適用於測試各種邊緣案例,以進行使用者輸入驗證。 測試已知的邊緣案例和錯誤案例都很有用。 模糊也有助於測試較不明顯的案例。

自動化和回歸

定期執行這些測試,並將結果與先前的執行進行比較,以攔截重大變更或效能回歸。 此外,在許多不同的機器和安裝安裝程式上執行這些測試,有助於涵蓋可能來自不同架構或設定變更的任何問題。

損毀傾印

這些測試有助於找出可靠性的問題,能夠測試許多可能遇到當機、停止回應、死結等不同案例。 藉由收集損毀傾印作為測試失敗的一部分,您可以將傾印直接匯入 Visual Studio,以進一步調查程式代碼中哪些部分遇到這些問題。 如果您從 Visual Studio 內執行功能測試,只要在黑箱內查看測試失敗的位置,即可輕鬆地複寫和偵錯失敗,而且您可以快速測試修正程式。

若要開始使用偵錯測試,請參閱 使用測試總管對單元測試進行偵錯 - Visual Studio (Windows)

在 Azure 中

Azure DevOps 也可以使用 Test Plans 來協助管理和驗證這些測試。 這些測試可用來確保使用手動驗證核准,以及執行與產品需求相關聯的自動化測試。 如需有關 Azure Test Plans 及使用這些方案來執行自動化測試的詳細資訊,請參閱這裡:

2.7 程式代碼型測試案例

摘要

以程式代碼為基礎的測試案例是維護產品安全性和可靠性不可或缺的一部分。 這些測試應該很小且快速,而且不應該彼此產生影響,因此可以平行執行。 只要開發人員變更程式代碼,就能輕鬆地在開發計算機上本機執行程序代碼,而不必擔心開發週期變慢。

類型與其他區段的關聯

程式代碼型測試案例的常見類型包括:

  • 單元測試,
  • 參數化測試以涵蓋具有多個輸入類型的函式,
  • 元件測試,讓每個測試元件保持個別,以及
  • 模擬測試以驗證與其他服務通訊的程式代碼部分,而不需要擴展測試的範圍以包含這些服務本身。

這些測試是以撰寫的內部程式代碼為基礎,而黑箱測試則以產品的外部功能需求為基礎。

目標

透過這些測試,目標是達到程式代碼的高階測試涵蓋範圍。 您應該主動追蹤此涵蓋範圍,以及存在差距的位置。 當您新增更多測試來練習更多程式碼路徑時,程式代碼安全性和可靠性的整體信心會增加。

Visual Studio

Visual Studio 中的測試總管工具可讓您輕鬆地經常執行這些測試,並快速取得通過/失敗率和失敗位置的意見反應。 許多測試架構也支援 CodeLens 功能,以查看測試本身位置的測試狀態,讓新增和維護測試套件變得更容易。 [測試總管] 也可讓您輕鬆管理這些測試,讓測試群組、自定義測試播放清單、篩選、排序、搜尋等等。

如需詳細資訊,請參閱

Visual Studio 也隨附用來追蹤程式代碼涵蓋範圍的工具。 這些工具可讓您確保現有測試涵蓋您所做的程式碼變更,或新增測試以涵蓋新的和未經測試的程式代碼路徑。 這些工具也會顯示程式代碼涵蓋範圍百分比,以確保其維持在目標層級之上,以信賴整體程式代碼品質。

如需這些工具的相關信息,請參閱 程式代碼涵蓋範圍測試 - Visual Studio (Windows)

在 Azure 中

Azure DevOps 也可協助追蹤整個產品的程式代碼涵蓋範圍結果,做為建置管線程式的一部分。 如需詳細資訊,請參閱 檢閱程式代碼涵蓋範圍 - Azure Pipelines

2.8 歷史測試案例

摘要

歷史測試案例,也稱為回歸測試案例,防止舊問題再次重新出現,並增加產品的整體測試涵蓋範圍。 您應該確保修正 Bug 時,專案也會新增對應的測試案例。 隨著時間的修正,測試套件的整體健全性會持續改善,為可靠性和安全性提供更好的保證。

重要品質,與其他區段的關聯性

因為它們會測試 Bug 回歸,因此這些測試應該快速且容易執行,因此可以與 [程式代碼型測試案例] 一起執行,並參與產品的整體程式碼涵蓋範圍。 此外,使用客戶的實際範例來激發新的測試案例,是改善測試涵蓋範圍和品質的絕佳方式。

Visual Studio

Visual Studio 可讓您輕鬆地將測試新增至套件,同時進行變更以修正 Bug,並快速執行測試和程式代碼涵蓋範圍,以確保所有新案例都已考慮。 在撰寫測試的程式代碼中參考問題追蹤系統中的錯誤標識碼,是將回歸測試連接到對應問題的好方法。 偏好搭配 Visual Studio 使用 Azure Boards 和測試方案:

  • 將測試、測試案例和問題產生關聯;和
  • 追蹤問題及其對應測試的所有層面。

如需詳細資訊,請參閱

最後,將這些測試整合到本應涵蓋程式碼區段的單元測試區域,有助於讓測試套件組織且更容易管理。 您可以使用測試總管的測試群組,有效地追蹤屬於一起的測試。 如需詳細資訊,請參閱 使用測試總管執行單元測試 - Visual Studio (Windows)

2.9 模糊

摘要 模糊(也稱為模糊測試)是自動化軟體測試技術,涉及提供無效、非預期或隨機數據作為程序輸入。 接著會監視程式是否有例外狀況,例如當機、失敗的內建或編譯程式插入的程式代碼判斷提示和潛在的記憶體流失。

指引

針對可能處理攻擊者可控制之不受信任輸入的所有軟體使用模糊。 如果您要建置新的應用程式及其相關聯的測試套件,請儘早包含密鑰模組的模糊。 第一次在軟體上執行模糊,幾乎總是會發現先前未知的實際弱點。 一旦你開始模糊,永不停止。

與其他區段的關聯

模糊報告失敗時,它一律會自然提供可重現的測試案例來示範 Bug。 此測試案例可以重現、解決,然後新增至歷史測試案例。

同時使用兩種清理工具時,例如 Address Sanitizer (ASan) 和模糊:

  • 請先執行已啟用清理器的一般測試,以查看是否有問題,然後程式代碼一旦清理程序開始模糊化。
  • 針對 C 或 C++,有編譯程式可將啟用 ASan 的運行時間判斷提示和元數據插入自動化。 針對 ASan 編譯時,產生的二進位檔會連結至運行時間連結庫,其可精確診斷 15 個以上類別的記憶體安全性錯誤 ,並出現零誤判。 當您有來源時,針對 C 或 C++,請使用 LibFuzzer,這需要先啟用 ASan。
  • 針對以 Java、C#、Python、Rust 等撰寫的連結庫,請使用 AFL++ 架構

關鍵品質

  • 模糊發現靜態程式分析、詳盡的功能測試和手動程式代碼檢查經常遺漏的弱點。
  • 模糊是尋找軟體中安全性和可靠性 Bug 的有效方法,因此 Microsoft 安全性開發生命週期 需要模糊處理每個產品不受信任的介面(另請參閱威脅模型化)。
  • 一律針對可能處理不受信任輸入的軟體使用模糊。
  • 模糊對於具有大型數據剖析器的獨立應用程式而言很有效。

Azure 和 GitHub CI/CD

修改您的組建,以支持持續建立使用 LibFuzzer 或 AFL++ 的可執行檔。 您可以新增 OSS-Fuzz 或 OneFuzz 等服務模糊所需的額外運算資源。

2.10 Web 應用程式掃描

摘要

在 Windows 上的 Microsoft Visual C++ 範圍內,Microsoft 建議:

  • 偏好使用 Web 應用程式的 TypeScript、JavaScript 和 ASP.NET。
  • 請勿在 C++ 中撰寫 Web 延伸模組。 Microsoft 已被取代 ActiveX。
  • 將程式代碼編譯為Emscripten/WASM時,不再套用 C++ 和其他工具。
  • Microsoft 提供 RESTler,這是具狀態 REST API 模糊。

概觀和關鍵品質

Web 應用程式掃描器會透過其網頁進行編目來探索 Web 應用程式,並檢查其是否有安全性弱點。 此編目牽涉到自動產生惡意輸入和評估應用程式的回應。 關鍵是,Web 應用程式掃描必須涵蓋/支援:

  • 編錄您網路中的所有 Web 應用程式,包括新的和未知的應用程式,以及從少數應用程式調整為數千個。
  • 針對行動裝置所使用的軟體版本、SOAP 和 REST API 服務和 API 進行深入掃描。
  • 將安全性基本類型插入DevOps環境中的應用程式開發和部署。 這些基本類型可與編目程式搭配使用。
  • 惡意代碼偵測。

2.11 簽到 排除的軟體元件

摘要

處理您的 C++ 程式代碼與其他程式設計語言撰寫的程式代碼相同,並將貴公司採用的任何軟體組合分析 (SCA) 和原始分析 (OA) 工具套用至您的 C++ 程式代碼。 工作流程和安全性掃描應設計為 CI/CD(持續整合和持續傳遞)系統的一部分。

上游防禦

若要降低上游相依性攻擊的風險,第三方來源/元件應該儲存在企業控制的資產上,以針對該資產執行 SCA 和 OA 工具。

  • 當識別弱點時,工具應掃描併發出警示,例如: 首頁 |CVE
  • 針對應用程式/存放庫中包含的所有軟體元件執行靜態分析,以識別易受攻擊的程式代碼模式。

相依性防禦

執行並維護相依性的稽核,以驗證 SCA 和 OA 工具會考慮和涵蓋所有這類專案。

  • 元件應定期稽核並更新為最新的已驗證版本。
  • 套件摘要相依性。
  • SCA/OA 工具涵蓋並稽核來自單一摘要的所有套件相依性。

SBOM

產生 SBOM(軟體材料帳單),並列出產品的所有相依性,例如:

  • origin (例如 URL (統一資源定位器))
  • version
  • 一致性(例如 SHA-256 來源哈希),以及其他驗證一致性的方法,例如具決定性的組建。
  • 需要並稽核軟體相依性中的SBOM檔案,或作為組建的一部分產生,包括OSS(開放原始碼軟體)。
  • Microsoft 正在標準化並建議 SPDX (軟體套件數據 Exchange) 2.2 版或更新版本 |Linux Foundation 做為 SBOM 檔格式。
  • 建置確定性可用來獨立產生位相同的二進位檔,並提供完整性的獨立驗證:
    • 第一方或第三方重現證明
    • 其他技術,例如透過受信任的憑證來源進行二進位簽署,也可以提供二進位完整性的一些保證。

其他資源

Microsoft 解決方案包含下列指引和產品: