隨著網(wǎng)絡的發(fā)展,特別是移動互聯(lián)網(wǎng)的發(fā)展,網(wǎng)絡服務與我們個人生活聯(lián)系得越來越緊密;辦理金融業(yè)務,生活繳費,獲取資訊等等,都從線下搬到了線上。一個新的時代必將到來或者已經(jīng)到來,那就是萬物互聯(lián)的時代。與此同時,網(wǎng)絡安全事件頻發(fā),安全事故的危害越來越大,互聯(lián)網(wǎng)從業(yè)者需要越來越注重安全問題。這里分享一些心得給剛剛接觸網(wǎng)絡安全的開發(fā)者們。
一、“安全”是什么
對于沒有接觸過安全的開發(fā)人員來講,一個常見的問題是:如何寫出安全的代碼或做出安全的系統(tǒng)。為了找到答案,我們就必須對安全的定義有所了解。“安全”是一個很寬泛的概念,那這里給出一個很寬泛的定義:被保護的對象不被破壞、篡改、泄漏,系統(tǒng)功能可以正常運行。是不是一頭霧水?“安全”定義的關鍵問題是,什么是需要保護的對象,保護的需求是什么;沒有明確的安全的需求,我們就無法談論安全。比如常見的安全問題有,通信協(xié)議是否安全,數(shù)據(jù)存儲是否安全等等;此外還有運行環(huán)境是否安全,代碼是否安全。所以當我們想要寫安全的代碼或者實現(xiàn)一個安全的系統(tǒng)之前,我們可以先問問自己,我想要保護的對象是什么。不同的安全的需求,需要做出的安全的防護方式也是不同的。如果不知道你想要的是什么,那么你就不會得到它。
明白了安全的定義,下一個問題是:如何知道實施的安全措施是否足夠安全。安全防御和安全攻擊是一個動態(tài)博弈的過程,就像抗生素和細菌一樣,防御和攻擊的技術都在進行不斷升級。所以我們說沒有絕對的安全,安全問題是成本問題。通常我們需要尋找的是如何以最低成本來滿足我們安全需求的最佳實踐。
二、如何入門“安全”
孫子云“知彼知己,百戰(zhàn)不殆”,所以讀幾本黑客如何攻擊和防御的書是一個不錯的選擇。這些書的內(nèi)容可能會涉及到一些計算機的基礎知識,所以這些知識也是不可少的,否則只能做到知其然而不知其所以然。由黑客攻擊和防御的引子,又會引出計算機系統(tǒng)、網(wǎng)絡、計算機體系結構、編譯原理、虛擬機等等一些基礎的知識。
黑客如何攻擊和防御是理論基礎,有了理論基礎我們可以看看這個真實的世界存在哪些比較流行的安全問題;CWE是通用缺陷,里面列舉了很多通用的安全缺陷,我們可以先從最流行的25個問題看起,可以幫助我們在編碼的時候避免許多安全問題。如果開發(fā)的系統(tǒng)是Web系統(tǒng),那么OWASP是不容錯過的一個資料庫;OWASP包含Web常見的問題和最佳實踐,可以了解一下OWASP最流行的10個問題。比如SQL注入,這種常見的高發(fā)的已經(jīng)有了幾十年歷史的問題,在這兩個榜單中都有提及。
接下來我們可以看看業(yè)界比較好的安全實踐。SEI CERT Coding Standards是一個安全編碼標準,分門別類得列出了C、Java等語言常見的安全問題,并且對安全問題做出解釋,給我們提供了不安全的代碼樣例和安全的代碼樣例。這個規(guī)范是一個很好的切入點,幫助我們快速了解安全問題,實踐安全編碼。
三、對“安全”問題的宏觀分類
安全問題五花八門,令人眼花繚亂,那么這些安全問題是否有共性呢?答案是有的。我們嘗試將安全問題分入以下幾個宏觀類別之中。
1. 不受信的輸入、輸出
壁立千仞,無欲則剛;如果一個系統(tǒng)沒有與不受信的環(huán)境進行的交互,那么這個系統(tǒng)的安全問題是比較小的。大多數(shù)系統(tǒng),特別是Web系統(tǒng),需要和不受信的環(huán)境進行交互;在交互過程中,我們需要特別注意的問題有兩點:輸入是否合法,輸出數(shù)據(jù)是否包含敏感信息。
輸入數(shù)據(jù)包括并不限于用戶輸入的參數(shù),傳入的文件,讀取的環(huán)境變量,依賴的運行庫等等。如果用戶輸入的數(shù)據(jù)超出程序處理的范疇,那么可能造成意想不到的結果。對于這些不受信的數(shù)據(jù),我們通常可以限制輸入范圍,只接受我們可以處理的輸入,比如網(wǎng)站注冊時對密碼的符號有一些限制,就是這種解決方案;我們還可以將輸入的數(shù)據(jù)進行清洗,去除不支持的內(nèi)容。
對于輸出數(shù)據(jù)我們需要關心輸出的內(nèi)容是否包含敏感信息,比如程序路徑、用戶名、密碼、IP地址等等。如果我們泄漏了服務器的用戶名和密碼,那么服務器上的所有信息都有泄漏的風險。這需要我們在程序發(fā)布之前,仔細檢查輸出內(nèi)容。
2. 程序本身有錯誤
如果程序本身有錯誤,那么就會給攻擊者可乘之機;一旦程序觸發(fā)到錯誤邏輯,程序有可能偏離正常的運行流程,比如運行了攻擊者提供的程序。
對于C語言來講,常見的程序錯誤有空指針引用、內(nèi)存沒有釋放、多次釋放內(nèi)存、數(shù)組引用越界、返回棧上地址、整數(shù)溢出等等。這需要代碼編寫者提高代碼編寫質(zhì)量,盡量減少程序錯誤。
對于Java語言來講,不存在C語言中的內(nèi)存管理類似的問題,但一樣存在整數(shù)溢出、數(shù)組引用越界、引用空對象等問題,此外,Java語言還存在錯誤調(diào)用運行時庫函數(shù)、類型定義錯誤、序列化和反序列化錯誤等等Java語言特有的問題。
3. 其它錯誤問題
我們將其它安全問題歸入單獨分類,這些安全問題包括并不限于以下幾點:
業(yè)務設計錯誤:如沒有經(jīng)過認證就讀取用戶信息
通信協(xié)議不安全:如使用了不安全的加密、散列算法
調(diào)用的庫不安全:如Web Server存在安全漏洞
……
四、一些安全實踐的建議
安全問題不是紙上談兵,而是真刀**實踐出來的,只有在實踐中才能出真知,安全性才能得到提升,這里給大家一些小的建議。
第一個建議是重視安全問題,針對安全問題進行設計和實現(xiàn),并且針對安全問題進行測試。西方哲人講“解決問題的第一步是承認問題”,老子講“知不知”,都是此意。
第二個建議是發(fā)現(xiàn)和利用工具幫助解決安全問題。業(yè)界已經(jīng)存在許多工具可以在各個階段幫助我們檢測安全問題。
語法檢測工具,避免一些低級錯誤;
靜態(tài)檢測工具,在開發(fā)過程中,對程序進行靜態(tài)檢測,可以檢測程序安全問題,可以分析庫文件是否存在漏洞,這是解決安全問題十分有效的手段;老牌的靜態(tài)檢測工具有OCLint,F(xiàn)ortify,Coverity,Checkmarx等,一些新秀也在冉冉升起,例如鑒釋的XcalScan;
動態(tài)檢測工具,將程序運行起來檢測安全問題;比如可以用Valgrind,Panda等工具;
自動化滲透工具,可以模擬滲透行為,對系統(tǒng)進行滲透以發(fā)現(xiàn)安全問題;比如有Zed Attack Proxy,W3AF,Wapiti 等等工具。
安全問題不是某一個單點問題,它是系統(tǒng)問題,這里沒有銀彈,沒有包治百病的特效藥。我們能做的是,在安全問題發(fā)生以前,充分了解、模擬、預警問題,并作出有效的防范。我們做的防護越多,攻擊者的攻擊面就越窄,攻擊成本就越高,我們的系統(tǒng)發(fā)生安全問題的概率就越低。千里之行,始于足下;現(xiàn)在就開始了解、重視安全問題,正當其時。