輸入驗證可避免一半以上的應用安全攻擊
俗話說病從口入,可以說絕大多數的應用安全問題的源頭都是由輸入的入口引發,但是輸入入口安全檢測不能解決所有的潛在安全問題,原因很簡單,那就是接收輸入的數據時,接收者并不知道此數據用來做什么,涉及的業務邏輯是什么,所以無法在輸入入口處進行完備而妥善的安全檢測與處理。但是,還是要強調一下這個“但是”,我們不能因為此處不能解決所有的問題而放棄它忽略它,本文將告訴你:做好完善合理的“輸入驗證”,可以解決50%(只是經驗值,后文不再解釋)以上的企業應用安全攻擊。
概念解釋:
1.輸入
廣義的“輸入”是相對于發送端與接收端的一個相對的概念,對于基于HTTP的web應用程序,那就是來自于瀏覽器這一端發往HTTP服務端請求數據包皆為輸入,以此類推,請求端的所有數據對于服務端來說皆為數據輸入。
2.輸入驗證
就是在服務端(強調一下:是服務端,而不是客戶端)依據業務邏輯的需要對來自于客戶端數據進行合法性校驗的過程。
我們先從兩個大家最熟悉的安全攻擊開始來看看它們與輸入的關系是什么。
例1,XSS(跨站腳本攻擊),大家可以在firefox上試一下這個測試鏈接:
http://www.testfire.net/search.aspx?txtSearch=<script>alert%2812345%29<%2Fscript>
這就是一個典型的反射式跨站腳本攻擊,它的過程是這樣的:字符串<script>alert%2812345%29<%2Fscript>通過HTTP的請求傳送到服務端,服務端經過自己的業務邏輯處理后返回到瀏覽器這一端,由于返回后未做正確的編碼,以至于在客戶端被瀏覽器執行。
例2,SQLInjection(SQL注入攻擊),大家也可以在firefox上測試一下這個鏈接:
這是一個典型的SQL注入問題,它的過程是這樣的,字符串admin%27+or+%271%27%3D%271的原型是:admin’or’1′=’1,這顯然是通過猜測應用程序后臺的實現方式,假設后臺程序實現人員通過把用戶的輸入拼裝到SQL查詢語句上進行SQL查詢的,以至于輕易的被黑客注入自編的SQL語句,騙過登錄驗證邏輯而成功以管理員身份登錄。
這兩個例子當中,輸入項有許多,我們只關注txtSearch/uid/passw這三個輸入點,它們是這兩個問題的輸入源,對它進行輸入驗證是否有意義呢?當然有。假如我們的業務邏輯上只要求txtSearch/uid/passw這個輸入點長度只需要15,數據類型只需要數字與英文字母即可滿足產品的設計需求,那么我們則可以這么做:
1)服務端獲取txtSearch/uid/passw的值
2)確認它的長度是否超過15
3)它的值是否只包含字母與數字
后臺實現上,只有以上條件完全滿足,再進行進一步業務邏輯處理,否則以友好的方式告知客戶端輸入非法。當然,為了更好的用戶體驗,可以在客戶端(假如是HTTPweb應用程序)用JS實時的動態提示用戶本處可以接受的合法輸入是什么。這么做的好處是什么?
1)對于第一個例子,如果我們因為疏忽或者某些未預料原因而導致XSS問題,由于你的限制足夠苛刻,以至于即便有XSS問題,黑客也難以對其進行很好的利用,因為有長度限制,也有字符集的限制。
2)對于第二個例子,如果我們真的因為實現上的疏忽而留下了SQL注入的安全問題,也會因為字符集、字符串長度的限制而讓黑客無法進一步利用它做更多的壞事兒。
以上只是拋磚引玉,象目錄遍歷、文件上傳、緩沖區溢出等等諸多應用安全問題,均可通過合理的正確的輸入驗證方式減少、降低甚至避免安全攻擊的發生。
關于輸入驗證,個人將其分為兩大類,一類是普通的字符串輸入,絕大多數是屬于這一類;另一類是支持富文本的輸入,比如文檔編輯、允許用戶輸入簡單標簽的輸入點。對于第二類,可以使用OWASP提供的AntiSamy(https://www.owasp.org/index.php/Category:OWASP_AntiSamy_Project)框架來輔助解決。
最后強調一下就是:我并沒有想表達做好輸入驗證就可以解決所有的安全問題,它的重要程度、利害關系及意義通過以上的描述,我想已經表達清楚了。做好輸入驗證的座右銘是:永遠不要相信來自于客戶端的輸入,這里的輸入不僅僅是顯式的用戶直接輸入,同時也包括隱式的協議數據包部分。