防患于未然:強化選擇編程語言時的安全意識
在軟件安全中,編程語言的選擇是一個重要因素。在許多情況下,老代碼、開發團隊中的可用技術或者客戶需求、環境等都可能限制編程語言的選擇。在評估和選擇編程語言時,你應當關注下面這些與安全相關的問題:
1、你的程序員用過哪些語言?在程序員使用自己基本沒有開發經驗的語言進行編碼時,就更有可能犯錯誤。
2、該語言有助于或有礙于安全代碼的開發嗎?
3、該語言有可用的安全編碼標準嗎?
4、該語言存在哪些安全問題?有哪些策略可以減輕其威脅?其有效性如何?
權衡語言的選擇:在許多情況下,語言的選擇會直接影響到系統的安全性。最顯著的例子是C語言和Java語言中數組邊界檢查的影響。雖然多數現代的C編譯器支持運行時的邊界檢查,但該特性會造成Web服務器、操作系統、應用程序等的緩沖區溢出漏洞,但對于性能等因素非常重要的環境(如嵌入式設備和智能卡)來說,就不是那么回事兒了。Java虛擬機可能會帶來太多的性能問題,導致潛在的服務被拒絕。類似的安全問題使得設計者或編碼者理解某種計算機語言存在哪些弱點非常重要。如果選擇了某種編程語言,設計者或編碼者知道哪些弱點更容易出現也很重要。
“安全”的語言:多數“安全的”語言(或語言的變種)都是用緩沖區、指針和內存管理來避免安全問題。由微軟開發的邊界檢查接口以及類似的接口都可以減輕由現有C程序中不正確的串管理所造成的漏洞。如果你要編制的程序將要在一個特定的暴露環境、手機、Web頁面中運行,就應當使用一種包含其自身安全模式和自我保護特性的語言(例如,Java)。還有一種選擇,即在主機系統上實現一種虛擬機,以包含和隔離所編制的程序。
靜態類型的好處:支持靜態類型的語言,如Java、F#等,都可以確保操作僅能應用于適當的類型。支持類型抽象的類型系統可以讓程序員指定新的抽象類型和簽名。這種類型可以防止沒有經過授權的代碼對特定的值實施操作。在這個方面,類型系統就超越了操作系統,因為它可以被用于強化更為廣泛的訪問策略類型。靜態的類型系統還可以通過靜態的檢查來支持離線強化,而不是根據特定的操作實例來檢查。這就使得類型檢查器可以強化難以通過在線技術強化的規則。
內建的安全機制:較新的語言,如C#,擁有內建到語言中的許多安全機制,其中包括類型安全元素、代碼訪問安全和基于角色的安全,這些安全機制都包括在.NET框架中。雖然.NET框架和C#包含許多有助于安全開發的要素,開發團隊仍有責任正確地開發和使用這些要素。注意,計算機語言仍有某些特性可以提供更多的安全性;不過,其它方面有可能打開新的安全漏洞。因而,對開發團隊而言,有必要知道由所選擇的語言導致的任何漏洞或問題。
有些語言可以通過限制程序能夠激發的系統調用,來減少一些不可信的程序可能帶來的破壞。Perl通過其“污染模式”來實現此功能,僅允許程序員明確設置為“清潔”的用戶輸入。 Java提供了JVM作為沙盒,并且不允許不受信任的程序在JVM之外運行。例如,一個不可信的Java小程序就不能創建新過程或者讀寫本地磁盤。
不要僅依賴語言的選擇:雖然選擇一種安全的編程語言很重要,但許多開發者者會錯誤地認為安全語言是安全漏洞的萬能藥。不過,如果沒有一個安全的開發過程,如果沒有知道如何安全編碼的開發人員,在將用一種語言編寫的軟件改為用另外一種語言編碼時,就很容易出現問題。
選擇健全的編程語言是編制安全程序的一個重要條件,但并非唯一要素。開發團隊應當根據項目特點、具體操作環境、開發團隊的人員素質等要素選擇合適的編程語言。