撰寫安全程式碼的方針
更新:2007 年 11 月
下列方針會提供數個撰寫安全程式碼的技巧。
必要項
使用程式碼分析工具。
Visual Studio Team System Development 版內含程式碼分析工具,可以大幅增加在程式碼中找到安全性 Bug 的機率。這些工具會更有效地尋找 Bug,而且較不費時費力。如需詳細資訊,請參閱偵測和修正 C/C++ 程式碼的缺失和偵測和改正 Managed 程式碼的缺失。
進行安全性檢閱。
每一次安全性檢閱的目標是加強已發行之產品的安全性 (經由修補檔案和修復檔案),或確保新產品在具有最大安全性之後才會發行。
不要隨機檢閱程式碼。請針對安全性檢閱事先著手準備,並從小心地建立威脅模型開始。如果您不這樣做,就會浪費大量的小組時間。針對需要大量安全性檢閱的程式碼設定優先順序,並且決定要優先處理的安全性 Bug。
在安全性檢閱中,請限定要尋找的問題。當您尋找特定的問題時,通常就可以找到問題。如果小組在某個區域中找到大量的安全性 Bug,請更加仔細地尋找 Bug,因為這就表示可能有必須修正的架構問題。如果找不到安全性 Bug,則通常表示安全性檢閱未正確地執行。
在接近開發過程的每個里程碑,以及由管理階層所決定之較大的產品上市進程點時,請舉行安全性檢閱。
針對安全性使用程式碼檢閱檢查清單。
無論您在軟體開發小組中的角色為何,準備一份可供遵循的檢查清單,有助於確保設計和程式碼能符合最低要求。
驗證所有的使用者輸入。
如果允許應用程式接受使用者輸入 (直接或間接),則必須在使用輸入之前先加以驗證。惡意的使用者會嘗試調整輸入以顯示無效的資料,讓應用程式失敗。使用者輸入的首要規則是:所有的輸入都是錯誤的,直到驗證為正確為止。
在使用規則運算式 (Regular Expression) 驗證使用者輸入時,請務必小心。對於複雜的運算式,例如電子郵件地址,您很容易認為進行了完整的驗證,但是事實上並非如此。因此,請讓同事檢閱所有的規則運算式。
對匯出之應用程式發展介面 (Application Programming Interface,API) 的所有參數嚴格地驗證其有效性。
請確定匯出之 API 的所有參數是有效的,這包括看起來一致的輸入但是超過可接受範圍的值,例如龐大的緩衝區大小。不要使用判斷提示 (Assert) 來檢查匯出之 API 的參數,因為在發行的組建 (Release Build) 中,這些判斷提示會遭到移除。
使用 Windows 密碼編譯 API。
您不需自行撰寫密碼編譯軟體,反之,請使用現成的 Microsoft 密碼編譯 API。藉由使用來自 Microsoft 的密碼編譯 API,程式開發人員可以心無旁鶩地專注於建置應用程式。請記住,加密 (Encryption) 只能妥善解決一小部分的問題,而且常常會被用於設計原意以外的用途。如需詳細資訊,請參閱 MSDN Library 中的 密碼編譯概觀。
請避免
緩衝區滿溢 (Buffer Overrun)。
在堆疊上宣告的緩衝區因為複製大於緩衝區的資料而遭到覆寫時,就會發生靜態緩衝區滿溢。在堆疊上宣告的變數會位於緊鄰在函式之呼叫端返回位址的位置。緩衝區滿溢也會發生在堆積 (Heap) 中,這也一樣危險。最常見的原因,是傳遞至例如 strcpy 這類函式但未受檢查的使用者輸入,而結果則會導致攻擊者所選定的位址覆寫函式的返回位址。因此若要有效避免緩衝區滿溢,就必須撰寫穩固的應用程式。
檢查外部輸入的判斷提示。
判斷提示不會編譯到零售版本中,因此不要使用判斷提示驗證外部輸入。所有匯出之函式和方法的參數、所有的使用者輸入以及所有的檔案和通訊端 (Socket) 資料,都必須要小心地驗證其有效性,如果有錯誤則要拒絕。
硬式編碼的使用者 ID 和密碼組。
不要使用硬式編碼的密碼,請修改安裝程式,使得建立內建使用者帳號時,能夠提示系統管理員為每一個帳號建立強式密碼。如此,就可以保持客戶實際執行系統的安全性。
使用加密解決所有的安全性問題。
加密只能妥善解決一小部分的問題,而且常常會被用於其設計原意以外的用途。
標準檔案路徑和 URL。
請避免造成檔案位置或 URL 是很重要的情況。請使用檔案系統 ACL,而不是根據標準檔案名稱的規則。
建議事項
檢閱應用程式中所有舊的安全性缺失。
以往所犯的安全性缺失,都可以讓您更了解這部分的知識。通常程式碼會以重複的模式撰寫,因此某個人在程式碼某處所犯的 Bug,表示可能會有其他人在其他地方也會犯相同的 Bug。
檢閱所有的錯誤路徑。
通常錯誤路徑中的程式碼不會被詳細地測試,而且不會清除所有的物件,例如鎖定或已配置的記憶體。請小心地檢閱這些路徑,並視需要建立錯誤插入測試以執行此程式碼。
不建議事項
應用程式需要系統管理員權限才能執行。
應用程式應該以完成工作所需之最低權限執行。如果惡意使用者找到安全性弱點,並將程式碼插入到處理序 (Process) 中,則惡意程式碼會和主機處理序以相同的權限執行。如果處理序以系統管理員身分執行,則惡意程式碼也會以系統管理員身分執行。如需詳細資訊,請參閱 MSDN Library 中的開發安全的應用程式 (英文)。