身為一位程式人或軟體專案主管,總希望自行開發出的系統是安全的,但基於不同動機的系統開發,所要考量的安全性需求可能不同。不過想要撰寫安全的網頁程式碼,有些原則還是通用的,那會是什麼?業界目前是否有最佳實務或理論可供參考?
當你身為一位軟體開發人員或軟體專案主管,面對當今層出不窮的資安事件,總希望自己開發出的系統是安全的。你的軟體開發專案對安全等級的需求,會因為需要於市面上銷售或者是於組織內部自行使用,而有不同的安全性需求。當然最務實的作法是先評估你的系統對資訊的「私密性」、「資料完整性」以及「可用性」三個面向的需求,以決定需要投入多少的工夫與成本來滿足安全性的需求。
實務一,絕對不要信任來自系統外界輸入的任何資料
系統開發時,如果都假設使用者都會乖乖的輸入正確的資料,那將會帶來許多的麻煩。因此,在程式中不管是承接使用者手動輸入的資訊,還是程式本身模組之間的參數傳遞等,都務必須要檢查這些輸入的資訊,以確認內容的正確性。這些檢查動作雖然是程式撰寫過程中很無聊的部分,且程式碼的行數也占很高的比例,卻是安全實務中最重要的部分,因為絕大部分的系統漏洞都是從這裡出發的。下面這些檢查是當今的應用系統中必須要貫徹執行的三類重點。
第一類、避免SQL Injection
在程式中如果要連接資料庫,以便執行資料的查詢、新增、刪除或修改的作業時,當SQL的查詢語法中需要含蓋使用者輸入資訊或者是系統外部參數時,請務必檢查內容格式以及字串的長度。如此將可避免產生出的SQL 查詢指令內包含了預期以外的SQL指令,而達到攻擊的目的。
第二類、避免Buffer Overflow
又稱為「緩衝區溢位」,這通常是撰寫C/C++程式時會遇到的困擾。由於語言的特性,經常性地須針對記憶體的陣列指標進行運用。當開發人員並未預先考慮外來提供的資料會大於內部所指定的緩衝區時,溢位會導致記憶體中的資料結構破壞,而這種問題經常會導致攻擊者得以執行惡意程式碼。
第三類、避免Cross-Site Script
又稱為「跨網站指令碼攻擊」,這通常是撰寫Web-based程式時會遇到的狀況。如果在輸出HTML資訊到使用者的瀏覽器的過程中,用到了使用者所輸入的資訊,或者利用其他模組所得到的結果字串來組合字串時,就特別需要執行特殊的內容檢驗程序,以避免輸入內容夾帶惡意的JavaScript,輕者破壞頁面排版,嚴重造成使用者的私密資訊被POST到其他網站中。
實務二,使用最低權限原則
幾乎每一種作業系統都有權限的安全性規畫,以維護程式執行環境的安全,能夠避免蓄意的破壞。因此系統開發時,應該避免整個系統只能以系統管理員的最高身分才能執行,即使有部分的程式需要較高的權限來存取與設定系統資源,也應當將它們隔離出較小的功能模組,並且透過呼叫的方式執行,讓應用程式本身仍可維持在較小的權限環境下運作。
另一個需要使用最低權限原則的實務作法是資料庫。如果你的應用系統對資料庫只需查詢資料時,就不需要搭配具有寫入資料權限的帳號。另外,避免直接將「sa」帳號用於應用程式中,因為如此一來,即便所有的防線都失效時,不會讓整個資料庫管理系統都淪陷。
程式在開發時,也需要留意用一般使用者身分執行時是否會出現權限過大的問題。例如一般的使用者權限執行時,系統的「Program Files」資料夾中不應該允許資料寫入,更不可以將暫存檔放置其中,正規的做法是將設定與存取的相關資料檔案,都放置在標準的「Document and Settings」資料夾中。我想大部分的開發者都是在系統管理員的模式下開發與測試的,因此測試的情境中,請記得納入用一般使用者身分執行的條件。
實務三,留意程式錯誤狀況的處理
其實,誰都不希望程式有任何的錯誤,但是相信吧!不管你多麼地小心,甚至經過完善的測試,沒有人願意相信有100%不發生錯誤的程式。因此系統在開發時,企業一定要花足夠的時間重新檢查錯誤、例外偵測、攔截與處理的相關程式中,並且確認所模擬的任何錯誤情境,都會正確地走到你預先埋好的錯誤處理函式中。
關於錯誤狀況的處理,還需要再確認︰當任何模組發生錯誤時,都記得要讓該模組的狀態恢復到執行之前的狀態,例如請求的記憶體區塊是否有正確地釋放,開啟的檔案執行完畢後是否都關閉,暫存檔案是否最後都清除等,讓作業系統恢復到安全的狀態。