搜尋此網誌

2009年6月9日 星期二

百密可別一疏 - 如何做好全面的Input Validation

Social Web這兩三年很紅,紅的不只是其受一般使用者歡迎的程度,而且也絕對是駭客的新寵。我個人雖然不常使用Social Web,但是或多或少還是無法避免,Facebook是我使用的其中之一。Facebook除了官方的功能,還提供了許多第三方開發的應用程式,這也是Facebook這麼熱絡的原因之一。話說這天我收到一個朋友發出的應用程式使用邀請,接受邀請想加入後不得了,出現了惡名昭彰的SQL錯誤訊息。雖然直接秀出SQL是不被接受的行為,但是我可也沒放棄這個機會。我稍微看了一下,原來就是’這個符號沒有處理好,而’這個符號剛好對SQL語法而言有重大意義。但是我再仔細想了一下,Facbook因為是全球性的網站,個人資料有’這個符號應該也不是完全不可能,至少我就看過人名是有’這個符號的。而我個人資料有’這個符號是出現在家鄉的省份(T'ai-pei),難道這個欄位有免受檢查的特權?所以,為了測試我的想法,我又申請了一個帳號測試這個問題。我這次申請的帳號除了所在地區同樣帶有’外,連姓名也加上了’,測試結果顯示姓名的’被移除了。雖然移除不是一個好的選項(因為這樣姓名就變了),但是至少不會造成程式執行的錯誤。所以應用程式的開發者的確知道該檢查使用者輸入的資料,但是卻沒有檢查到所有該檢查的資料。所以,就有了今天的主題。

Facebook應用程式的錯誤訊息

farmgame_001

如果你從事過軟體開發的工作,或接觸過軟體開發的工作,不管有沒有實際的經驗,至少都聽過一個很重要的建議,那就是要記得檢查使用者輸入的資料。這個建議成為人人朗朗上口的推手,一個很重要的因素就是Web的流行。因為Web的特色就是使用者的輸入來源各式各樣,而且都是不可控制的。也因此有許多的攻擊方法,基本上都是利用忘了針對使用者輸入的資料做檢查而產生的漏洞。像是鼎鼎大名的SQL Injection、Command Injection、XSS、CSRF等,都跟這個問題有或多或少的關連。

這句話聽起來很簡單,而且很也容易懂,但是有兩個很重要的問題需要釐清。第一個問題是甚麼叫做好的檢查方式,或者說是足夠安全的檢查方式。第二個問題則是有哪些資料應該檢查。在這篇文章中,我想針對的是第二個問題加以討論。

所以,有哪些資料需要加以檢查?使用者輸入的資料,以Web的系統來說,大家通常最先想到的就是URL 參數(Get 方式)與Form Data(Get/Post 方式)。因為這是主要用來接收使用者資料的兩種方式。在Form Data有一個特別需要注意的地方,就是隱藏欄位也同樣需要檢查。雖然一般使用者在正常的使用中無法看到與修改隱藏欄位的存在與內容,但是駭客既不是一般的使用者,通常也不會用正常的使用方式,所以隱不隱藏對有心份子來說是沒有任何差別的。

除了這些顯而易見的資料外,其實還有一個地方也是在使用者的完全掌握之中,那就是Cookie。雖然Cookie一般存在檔案中、有時甚至存在記憶體中,所以不方便或不可能直接修改其數值。但是HTTP協定的問題就是在於傳送Cookie時是不做任何加密的動作,所以任何人都可以攔截Cookie的內容,甚至是修改Cookie的內容。說任何人當然是誇張了點,但是在技術上並沒有甚麼特別困難之處,只消一個Intercepting Proxy (如WebScarab)就夠了。

Okay,Cookie我們也檢查了,可以放心了嗎?還不夠!HTTP協定中還有一種資料也是在使用者的掌握中,那就是HTTP Header。雖然我們在大部分的情況下不會使用HTTP Header的資訊,也不會直接利用它來處理使用者的資料,但是這類問題的嚴重依舊不可忽視。

使用者可以直接控制的資料都檢查過了,天下應該太平了。是的,只不過這已經是過去的美好時光。在現在的Web環境下,Web應用程式已經不再是一個單一的系統,而是由各式各樣的Widgets、Mashups等小元件所共同組成。這些小元件的特色就是由不同的人所開發,開發的語言甚至可能不同,種種得不同都代表了這些元件不受主要網路服務提供者的管理與潛在的安全問題。此外,分享的內容也由原先單純的文字,演化到圖片、網誌、影片等各種形式,而這些分享的方式與內容,也可能造成安全的危害。所以,光檢查使用者輸入的資料已經不再足夠,而是要檢查所有透過不是由你(的程式)所直接控制的資料來源所取得的資料。這些資料包括(但不侷限於)從其他網站所獲取的資料、檔案(尤其是使用者上傳的檔案)、資料庫的資料(這是一個特例,即使資料庫是”自己的程式”所維護,也需要加以檢查)、E-mail等。

回到Facebook應用程式的例子,我們發現其實T’ai-pei那串文字並不是使用者自行輸入的。我原先輸入的是Taipei,但是系統對應出來的選項卻是T’ai-pei。也或許因為這個字串是由系統產生的,所以應用程式的開發者就假設這個資料是安全的,所以也就認為不需要檢查。很可惜的是,這樣的假設是不成立的,所以就出現了這樣的錯誤。

有問題資料的乃是系統產生的字串

farmgame_002

2009 CWE/SANS Top 25 Most Dangerous Programming Errors中所公布的第一個錯誤正是不適當的輸入驗證(Improper Input Validation),而其對於哪些資料需要加以驗證有下列文字加以說明

“Understand all the potential areas where untrusted inputs can enter your software: parameters or arguments, cookies, anything read from the network, environment variables, request headers as well as content, URL components, e-mail, files, databases, and any external systems that provide data to the application. Perform input validation at well-defined interfaces.”

在SANS公布的內容中,針對如何加以檢查也有完整的說明,有興趣的讀者就請自行參考了。

相關連結:

About