觀點

如何做好網頁系統的Code Review

2010 / 05 / 07
林佳明
如何做好網頁系統的Code Review

網站服務預設是給匿名訪客來使用的服務。只要網頁程式的撰寫稍有不慎,就可能把整個電腦的控制權送給惡意的使用者。因此,對於網頁程式碼的檢視就是確保網頁程式安全的一項手段。一般來說,檢視方式可以分為兩類:內部檢視(原始碼檢視)以及外部檢視(黑箱測試)

 

內部檢視

內部檢視又可以稱之為原始碼檢視,顧名思義就是再一次的檢查程式的原始碼,確認網頁程式碼是否符合安全的要求。整個程式開發的過程,大致上分為「需求分析」、「系統設計」、「程式碼撰寫」、「系統測試」、「系統運行」。在開發的每個步驟中,就應該把程式碼檢視列入計畫中。在需求分析中,並不是只有收集使用者對於系統功能的需求,還要收集對於網頁系統的安全要求為何,記錄在需求表中。系統設計時依據對於程式碼安全的需求,設計出安全程式模組,讓程式撰寫人員有準則可以依循。在程式碼撰寫的時候,就必須開始執行原始碼檢視的工作,而不能等到系統測試時,才進行檢視。如果開發人力充裕,可以使用雙人開發小組的模式。讓兩個人一組一起寫同一個功能、頁面的程式。由於人在寫程式的時候一定會有盲點(不論是邏輯上的錯誤、或是記憶上的錯誤),會容易犯錯。所以兩個人一組一起寫程式,可以讓其中一個人主寫程式,另一個人輔助檢查程式的效率、功能、以及安全性。同時,最好能夠讓兩個性格不太相同的人一組,才比較能夠發覺到另一個人在撰寫程式時的遺漏(例如,如果找了兩個都不喜歡寫註解的設計師成為一組,就容易發生程式註解不完全的狀況)

 

如果單位本身的程式開發人力不足,或者開發時程緊縮等,無法實現兩人一組的狀況下,我們也建議,程式設計師在做功能測試時,也應該自己再做一次原始碼的檢視。一般來說,程式設計師對於網頁程式原始碼的檢視,檢視四個部分:

1.邊界檢查:針對程式傳入參數的數值進行檢查。(例如:使用

   者輸入帳號密碼,程式就該檢查使用者是否輸入了「脫溢字

    元」)

2.檔案存取檢查:檢查程式是否做了存取控管,以及存取控管

   是否有缺失。(例如:不需要登入就可以存取管理介面)

3.邏輯檢查:檢查程式執行程序上是否存在邏輯錯誤。(例如:

   電子購物產品的價格來自於網頁傳入的參數)

4.錯誤回應檢查:檢查程式執行錯誤的回應是否安全。(例如:

   使用者輸入帳號密碼錯誤時,僅回應登入錯誤,而不可以回

    應帳號不存在或密碼錯誤)

 

因此,為了方便、快速的進行原始碼檢視,程式開發人員對於特定資訊的『註解』是非常重要的。舉例來說,在程式開頭應註解說明程式名稱、程式功能、傳入參數名稱以及類型(最好能夠說明參數的作用)、程式存取權限。讓進行原始碼檢視的人員,可以快速的從程式開頭就知道要檢視的項目有哪些,進而縮短檢視的時間以及降低誤判率,以及在特定的程式段落也給予特定的註解字串。例如,在發送資料庫查詢語法的程式段,註解一個特定字串「資料庫查詢,請檢查」,提醒檢視人員要特別注意檢視哪一段程式碼。

       

最後程式開發進入到整合測試的時候,負責測試的人員,除了必須將上述的四種原始碼檢視方法再進行一次。還必須在程式正式上線使用前,負責移除程式設計師所撰寫的註解。程式設計師所編寫的註解,目的是用來幫助提升檢視原始碼時的效率,所以可能會記錄到一些敏感的安全性資料,導致讓惡意的使用者可以透過這些資訊進行網站的攻擊、資料的竊取。在程式碼轉移到線上系統前,一定要確保程式碼註解經過移除。

 

外部檢視

外部檢視又可以稱之為黑箱測試,顧名思義就是在沒有取得程式原始碼的條件下,使用外部掃描、檢查的方式,確認網頁程式碼是否符合安全的要求。外部檢視並不代表僅能讓外部的廠商、檢測人員來進行,公司在進行整合測試的時候,也可以使用外部檢視的技巧來進行程式的分析。外部檢測由於沒有辦法看到網頁程式的原始碼,所以大都是使用掃描工具來進行程式碼安全的檢測。

 

這些工具最基本的功能之一,就是要能夠擁有探索網站的功能。亦即,掃描工具必須能夠掃描出一般權限下網站提供哪些檔案、連結以供使用者存取。如果是整合測試的人員拿到掃描出來的掃描列表,可以直接比對程式註解中的「程式存取權限」,看看是不是發生了權限控管失當的狀況。而外部的檢視人員在沒有原始碼的狀況下,就必須檢查每個網頁的內容,藉以判斷該網頁是否未設定適當的存取權限。

 

而掃描工具也應該要能夠對網頁程式所傳入的參數進行邊界檢查工作。這邊介紹一個在Windows平台上執行開放原始碼的掃描工具?RPVS - Remote PHP Vulnerability Scanner」,讓讀者可以體會到掃描工具的大概功能。使用「RPVS - Remote PHP Vulnerability Scanner」當成關鍵字,透過搜尋引擎就可以找到程式的下載點。RPVS是在CMD模式下運行的工具,筆者使用1.2的版本提供如以下參數。

 

掃描結果如下圖,會判斷是否存在incXSS弱點或者網頁程式是否錯誤的處理inc檔案、SQL錯誤訊息、引用fopen函數。

 

RPVS的缺點是只針對PHP程式進行邊界檢查,以及不會將掃描過的網頁連結給存檔顯示。不過,所幸RPVSOpen Source的程式,懂得C++語言讀者可以自行修改程式碼來符合讀者的需求。RPVS的運作方式,是先掃描探索網站在一般權限下,網站提供哪些檔案、連結以供使用者存取。並將脫溢字元或特定攻擊字串傳入網頁中,然後從伺服器的回應來判斷是否有回應出可被判定出存在特定弱點的字串。例如,出現SQL語法執行錯誤的字串(MySQL: A link to the server could not be established in),就可以判定為,該網頁程式存在SQL injection的弱點。

 

網頁安全解決方案

筆者因為工作職務需求,會至針對政府機關舉辦的資安講習中,說明關於網站安全弱點相關的議題,會後常常會有人詢問這樣的問題?「請問!我們怎麼知道或判斷廠商所撰寫的程式是否有SQL injection弱點?有沒有免費的軟體可以使用?」。據筆者目前所收集到的工具,並沒有一套「免費又完整」的網站弱點掃描程式;大部分免費的「外部檢測」軟體,都會有他的限制。例如,只針對特定的網頁程式與資料庫類型(如,RPVS只針對PHP程式、許多中國大陸所開發的工具只針對ASP程式搭配MS SQL資料庫進行檢測。)而且,外部檢視有三個很大的缺點:第一,檢測工具對於網站探索功能的強度。由於網頁程式存放超連結的方式已經不再是單純的使用HTML Tag-<a href></a>,還會使用JavaScript來存放超連結(例如,Window.open())。如果,檢測工具,沒有將各種可能會開啟超連結的JavaScript寫在程式裡面,就會造成檢測上的遺漏。而這些被遺漏沒有檢測到的網頁,就可能會變成隱藏的弱點。第二,檢測工具對於弱點存在與否的判定方法上會存在缺點。如果用以判斷是否存在弱點的特殊字串資料庫不夠完備,就有可能將存在弱點的網頁誤判為沒有弱點。再者,檢測工具是否使用每一種的脫溢字元,甚至是組合多樣化的脫溢字串來測試網頁程式,或僅用少數脫溢字元來測試網頁,都會影響檢測程式的判斷率。第三,檢測工具很難檢測出程式邏輯上的錯誤。

 

因此,解決網頁程式是否存在弱點的根本方法,最好就是進行原始碼檢視。因為,外部檢測會依據檢測人員的技術能力、檢測工具的限制而有不同的結果(而且以現階段來說,大部分的資訊人員都沒有能力進行外部檢測)。對內部的檢視人員來說,完整的工具不易取得(除非自行開發),唯一可靠又可以取得的資訊,就是手邊的原始碼。最簡單的檢視方式就是,檢查每一個變數是否已經將脫溢字元給剔除。這樣才能確保每一個網頁的程式都有被檢視過。

 

如果讀者想要尋找檢視廠商、檢視工具的相關訊息,可以參考「資安大黑洞」這篇文章。想要知道怎麼修改程式避免SQL Injection的攻擊可以參考《資安人》第25期「檢測與修復SQL INJECTION」一文。而XSS的弱點相關資訊可以參考「跨網頁攻擊對企業網站的影響」。