訪問控制、防火牆、入侵檢測系統,以及入侵防御系統組成了一個完整的應用程序安全防線,向應用程序提供了全方位的保護。但是,這些機制並不能百分之百地防御網絡應用程序攻擊。因為這些應用程序是基於網絡的,網絡用戶與應用程序進行的通訊支持直接的網絡攻擊,使得已建立的安全防線保護形同虛設。攻擊者意識到了這一點,因此直接的網絡應用程序攻擊是當前大多數網絡攻擊類型。
為了平衡這種狀況,應用程序開發人員必須有意識來建立防御攻擊的策略。他們必須要考慮一些構成一系列網絡攻擊方式的因素:
大多數的網絡應用程序開發人員都不是安全方面的專家,也不會意識到大多數存在的問題。
許多開發人員都不會意識到網絡應用程序開發中的最佳安全實踐方式。
功能通常最受人重視,而安全性問題都會在最後才會得到處理。
部署網絡應用程序的環境通常都會發生變化,包括應用程序代碼自身的更新,以及基礎設施的變化。有一些更改沒有受到安全領域專家的足夠重視。
如果每一個應用程序開發人員都考慮以下因素的話,那麼他們可以寫出更好的代碼。
得到培訓。
查找建立的模式。
將測試集成到開發計劃之中。
及早報告漏洞的存在。
本文旨在幫助一些開發人員和部署人員,處理一些影響到 Web 2.0 應用程序的常見網絡應用程序安全問題。文中還提供了一些關於移動設備特定安全性問題的介紹。
常見的網絡漏洞
移動網絡應用程序所遇到的網絡安全性問題與桌面網絡應用程序所遇到的情形很類似。學習更多關於這些問題和反制措施的資源庫是 Top 10 Project on the Open Web Application Security Project(OWASP)網站(參見 參考資料)。
接下來的部分介紹了開發人員必須理解的頂級問題。
跨網站腳本
在這種一般的攻擊中,惡意代碼會植入到第三方的受信網站之中。如果 HTTP 請求可以將其注入到最終 HTML 頁面上的話,那麼跨站點腳本漏洞就向這種攻擊開放了。
例如,一項服務會接受名為 image 的參數,來接受來自於文件系統的圖片,來執行一些處理:
http://somedomain/myImageProcessor?image=myimage.jpg
一個入侵者可以通過向 image 參數插入 JavaScript 代碼,來占用該應用程序。其意圖是耗盡錯誤處理系統的資源。如果一個包含惡意腳本的出錯信息會被生成的話,那麼入侵者就可以利用這一點了:
http://somedomain/myImageProcessor?image=myimage.jpg
如果出錯信息返回圖片參數的內容,而不用篩選的話,那麼代碼就會封閉到 作為搜索關鍵字輸入時的結果。腳本代碼會在搜索結果中顯示出來,代碼會得到執行,而警告窗口也會顯示出來。
圖 3. 輸入“JavaScript”作為 JavaScript 執行中的搜索詞語結果
反制措施
按照下面的方法來避免跨網站腳本(XSS):
不要向用戶顯示不受信任的輸入。
采取措施預處理輸入與輸出,以刪除惡意代碼,例如篩選或者 白板列表(定義什麼是允許輸入的,什麼是不允許輸入的)。
Encode 輸出以避免浏覽器執行。
對於 Altoro Mutual 來說,一個簡單的修復操作將不會返回搜索結果。
為了進一步深入討論跨網站腳本以及預防措施,您可以閱讀 developerWorks® 文章“IBM Rational AppScan:跨站點腳本攻擊深入解析”,或者在 Open Web Application Security Project(OWASP)培訓頁面上了解到關於跨網站腳本的內容。(參見 參考資料 以得到資源的鏈接)。
SQL 注入
這種攻擊同樣關注於找到請求的缺點,然後向網絡呈現的輸入區域插入一個 SQL 條目。能夠插入查詢作為輸入區域一部分的入侵者可以輕松繞過一個網站的認證機制,並訪問數據庫。這種攻擊,與跨網站腳本一起已經泛濫了。
這種范例向您展示了怎樣使用 SQL 注入來耗盡一個結構糟糕的登錄應用程序:
一個網絡應用程序會催促您輸入一個用戶名和密碼來進行登錄,而 SQL 語句是按照下面的方式組織的:
String query = "SELECT * FROM users WHERE user ='"username+"' AND password ='"passwd"'";
變量 username 以及 password 沒有得到細致的處理,並分配給用戶在應用程序中輸入的值。這就使得一些惡意的用戶可以輸入 username 之類的值:
anything' OR 1=1 --
密碼可以是任意值。在這種情況下,假設它是一個星號:*。
對於輸入來說,當代碼替換 username 以及 password 變量時,結構化的查詢是:
SELECT * FROM users WHERE username ='anything' OR 1=1 -- AND password ='*'
該語句解釋了密碼需求,並插入狀況 1=1,這條語句的值一直都是真的。就算沒有相關的權限,攻擊者也會被確認為一個有效的用戶。
這種攻擊在 Altoro Mutual 網絡應用程序進行了演示(參見圖 4)。切換至登錄頁面,並輸入 anything' OR 1=1 -- 的用戶名以及任意的字符作為密碼,就可以作為管理員登錄了(圖 5)。該賬戶有控制其他用戶賬戶的權限。
圖 4. 嘗試用任意的一個用戶名以及一段 SQL 代碼作為密碼進行登錄
圖 5. 執行 SQL 注入攻擊之後攻擊者作為管理員登錄
就像跨網站腳本一樣,這種攻擊是糟糕的或者根本不存在的輸入檢驗和確認系統造成的結果。
反制措施
您可以執行以下操作以防御這種攻擊:
不信任來自用戶的所有輸入。
采取措施來檢驗用戶的輸入,例如篩選或者白板列表。
在 Altoro Mutual 案例中,一個可能的解決方案是篩選來自 Username 與 Password 區域的非字母數字字符。
如果您想要得到更多關於 SQL 注入以及可能反制措施的信息,您可以閱讀 OWASP 培訓頁面以了解 SQL 注入(參見 參考資料)。
信息洩露
一個有意志的攻擊者可以通過識別缺點來研究一項應用程序。例如,一個攻擊者可以按照不同的方式來獲取信息:
手動研究應用程序以做到隱藏的目錄
系統性地收集例外情況,以查看應用程序是否給出了詳細的例外情況
掃描 HTML 以得到揭示應用程序基礎及行為具體內容的注釋
系統性地輸入用戶名以找出已存在的賬戶
Altoro Mutual 應用程序會在系統之中洩露已存在的用戶名。例如,在圖 6 中,輸入一個不正確的用戶名和密碼會產生這種出錯信息:“登錄失敗:抱歉,在我們的系統中找不到該用戶名。請重新嘗試。”
圖 6. 應用程序清晰地聲明系統中沒有做到該用戶
接下來,入侵者會嘗試用戶名 jsmith,而 Altoro Mutual 網絡應用程序會收到以下的信息:“登錄失敗:您輸入的密碼無效,請確認後重新輸入密碼”。於是,入侵者從以上信息上了解到有一個用戶賬戶名為 jsmith。在此基礎之上,入侵者可以把注意力放到破解密碼上面,或者使用暴力破解方法來發現密碼。
圖 7. Altoro Mutual 應用程序洩漏了用戶名 jsmith 的存在
在這種情況之下,修復方法可以是產生一種通用的登錄信息,不會精確地指出什麼地方沒有輸對,例如:“登錄失敗:用戶名或者密碼無效。請確認後重新輸入您的信息”。
反制措施
對於應用程序來說,信息洩漏需要受到人們的重視,開發人員的意識是最好的防御手段。記住這一點,開發人員可以考慮一些減輕問題的措施。
所有評論的清晰 HTML 代碼會揭示應用程序的實際情況。
不要在浏覽器中顯示特定的例外。如果必須登錄,將它們存儲在服務器上,並顯示常見的錯誤。
不要揭示哪一部分的認證錯誤。
同樣,配置網絡服務器和應用程序服務器設置,以避免在網站和應用程序上任意的導航。
這種類型的信息洩漏不會再耗費您的精力了。查找特定應用程序和運行環境存在的其他洩漏問題。
您可以在 OWASP 培訓頁面上找到關於信息洩漏的更多信息。
參數干擾
這些類型的攻擊旨在控制傳遞給應用程序的參數。想象一下一段糟糕的應用程序讓客戶來設置要購買商品的價格。這一應用程序可以發送以下的請求:
http://somedomain/myStore?item=1234&price=$200
如果業務邏輯並不會在服務器端執行任何類型的雙重-檢查的話,那麼入侵者可以更改價格,以更低的價格買到商品。在這種情況下,允許從客戶端更改價格顯然是一個 bug。
反制措施
為了解決這一特定示例中的問題,您可以更改代碼以從服務器的數據庫端獲得價格的信息,避免價格控制問題的產生。