如何構(gòu)建安全的Web應用程序
多年以來,安全專家們都在警告人們Web應用程序的漏洞,而這些警告往往會變成現(xiàn)實。我們經(jīng)常看到這樣的報道:黑客成功地滲透進入了一個Web應用。黑客或網(wǎng)絡罪犯們也在共享新發(fā)現(xiàn)的漏洞,分享他們的成功故事或者對下一個目標的研究。我們不可能保證企業(yè)網(wǎng)絡絕對無法滲透,而且黑客們已經(jīng)證明了這一點,那么,為保障這些關(guān)鍵的企業(yè)應用,編程者應該做點兒什么呢?
本文討論在以安全為中心的計算機編程時,如何構(gòu)建低風險的基于Web的應用程序。
1.查詢參數(shù)化
有許多針對Web應用程序的攻擊可追溯到成功竊取了口令的SQL注入攻擊。企業(yè)、政府、社交網(wǎng)站都成為這種攻擊的受害者,這使其成為一個普遍的問題。雖然許多人認為這個問題是廠商問題,但從根本上講這屬于開發(fā)者的編程問題。
網(wǎng)頁表單的評論框、數(shù)據(jù)字段或允許自由輸入數(shù)據(jù)的表單區(qū)域,特別是開放性的字符串輸入,都會導致這種漏洞。SQL注入攻擊甚至可以通過非可見的Web元素(如HTTP的header的值)來傳遞。惡意的SQL代碼的簡單插入,有時會導致整個數(shù)據(jù)庫都有可能遭到竊取、清除或篡改,甚至被用來惡意地運行操作系統(tǒng)命令來破壞企業(yè)的數(shù)據(jù)庫。
為阻止SQL注入,開發(fā)者必須防止非可信的輸入被解析為SQL命令的一部分。阻止SQL注入的最佳方法是借助使用參數(shù)化查詢的編程技術(shù)。
例如,在java標準中,可借助如下方法實現(xiàn)參數(shù)化查詢:
String custname = request.getParameter("customerName");
String query = "SELECT account_balance FROM user_data WHERE user_name = ? ";
PreparedStatement pstmt = connection.prepareStatement( query );
pstmt.setString( 1, custname);
ResultSet results = pstmt.executeQuery( );
2.保證口令存儲的安全
顯然,如果SQL注入可被用于竊取口令,就需要我們安全地保存用戶口令。但為什么我們沒有這樣做?
保存口令的最糟糕的方法當然就是使用純文本;但是,加密也不會好很多。原因在于加密是可逆的,還有一個原因就是MD5或者任何其它的哈希算法都是 有問題的。當今的黑客們可以訪問強大但并非十分昂貴的計算資源,這可以使他們創(chuàng)建甚至購買“彩虹表”,從而可以實時地破譯一般強度的密碼。如今,黑客們甚至不再使用彩虹表,轉(zhuǎn)而使用高性能的家用計算機去執(zhí)行高速度的字典攻擊。密碼加鹽技術(shù)是一種有助于對付彩虹表攻擊和刪除口令哈希重復數(shù)據(jù)的編碼技術(shù),但僅有這種技術(shù)是不夠的。
利用有限的資源(如,利用并不昂貴的家用電腦),攻擊者可以生成GPU破解程序,針對存儲口令,它每秒鐘可以執(zhí)行250億次口令嘗試。
為存儲口令和防止GPU破解程序和類似的資源暴露口令,我們建議結(jié)合三種主要技術(shù):采用單向算法、加鹽、有意利用慢速算法。有兩個很好的算法,SCRYPT 和 PBKDF2可用來以這種形式安全地存儲口令。
3.輸出編碼的XSS防御
跨站腳本攻擊(XSS)有一個更合適的名字,即JavaScript劫持,它可被用于會話劫持、站點破壞、網(wǎng)絡掃描、破壞CSRF防御、站點重定向或釣魚、遠程托管腳本的加載、數(shù)據(jù)竊取和擊鍵記錄等,而且,攻擊者還越來越頻繁地使用XSS。
輸出編碼是一種用于阻止XSS的關(guān)鍵編程技術(shù),這種技術(shù)在輸出時執(zhí)行。在你構(gòu)建用戶界面時,這種編碼可以在不可信的數(shù)據(jù)被動態(tài)添加到HTML之前的最后時刻執(zhí)行。
首要的規(guī)則是拒絕所有,也就是不要將不可信任的數(shù)據(jù)放置到HTML文檔中,除非滿足特殊情況。最重要的是,千萬不要接受來自不可信源的JavaScript代碼。
4.內(nèi)容安全策略
內(nèi)容安全策略是一種新出現(xiàn)的瀏覽器標準。其基本理念在于創(chuàng)造一種標準化的框架,實現(xiàn)基于瀏覽器的保護,從而只需花費開發(fā)者用較少的工作就可以阻止XSS攻擊。
為了使內(nèi)容安全策略有效,嵌入到HTML中的所有JavaScript都需要清除,并部署在一個獨立的外部JavaScript文件中。從這一點來看,如果能夠理解內(nèi)容安全策略的瀏覽器檢測到了HTML文檔中嵌入的JavaScript(例如,黑客試圖插入這種腳本),該操作將被拒絕。這種做法能真正地鎖定瀏覽器,防止許多形式的XSS攻擊。
5.防止跨站腳本請求偽造
一旦用戶登錄進入了一個安全站點,然后打開了另一個標簽并無意中登錄了一個惡意網(wǎng)站,該問題站點可能包含有跨站請求,并充分利用用戶已經(jīng)登錄進入的事實。然后,該惡意站點可能提交虛假請求,帶來重大危害,如欺騙用戶將金錢從銀行網(wǎng)站轉(zhuǎn)賬。
為防止這類攻擊,開發(fā)者需要考慮部署加密令牌,并要求用戶重新進行身份驗證才能完成交易,從而防止會話劫持。
6.多因素認證
許多人認為口令作為一種單一的認證因素已經(jīng)死亡。更佳的認證方案是雙因素或多因素認證。總是要求用戶必須攜帶另一種設備才能驗證身份是不現(xiàn)實的,所以這兩種認證在過去已經(jīng)有了很大的普及。雖然MFA的SMS和本地應用并不完美,但確實可以減少風險。許多消費者網(wǎng)站和其它網(wǎng)絡服務現(xiàn)在提供多因素認證,如谷歌。
7.遺忘口令的安全設計
許多網(wǎng)站允許用戶用簡單的認證就可以請求原有口令或?qū)⑿驴诹畎l(fā)送到一個注冊的郵件地址。其實,更強健的過程應當是:用安全問題驗證身份;通過帶外方法(即SMS或令牌)向用戶發(fā)送一個隨機生成的密碼;在同樣的Web會話中驗證代碼并增強鎖定策略;用戶改變口令。
雖然上述步驟并不能根除現(xiàn)有的每個漏洞,也無法阻擊所有的攻擊要素,但這些措施卻有助于強化網(wǎng)站和應用程序。
應用程序的編程者應當學會用安全方式編寫代碼。這是企業(yè)安裝網(wǎng)站安全正確防御的唯一關(guān)鍵機會。