做web開發我們經常會做代碼走查很多時候我們都會抽查一些核心功能或者常會出現漏洞的邏輯隨著技術團隊的壯大組員技術日益成熟 常見傻瓜型SQL注入漏洞以及XSS漏洞會越來越少但是我們也會發現一些新興的隱蔽性漏洞偶爾會出現這些漏洞更多來自開發人員對一個函數常見 模塊功能設計不足遺留下的問題以前我們能夠完成一些功能模塊現在要求是要安全正確方法完成模塊才行 接下來我會分享一些常見功能模塊由於設計原因導致漏洞出現下面我們先看下讀取文件型功能漏洞
我們先看下下面一段代碼通過用戶輸入不同目錄包含不同文件
<?php
///讀取模塊名稱
$mod = isset($_GET[m])?trim($_GET[m]):index;
///過濾目錄名稱不讓跳轉到上級目錄
$mod = str_replace(""""$mod);
///得到文件
$file = "/home/www/blog/"$mod"php";
///包含文件
@include($file);
這段代碼可能在很多朋友做的程序裡面有遇到過對於新人來說也是很容易出現這樣問題記得走查遇到該代碼時候我問到你這個代碼安全方面能做到那些?
答 對””目錄有做替換因此用戶傳入模塊名裡面有有目錄都會被替換掉了
構造拼接file名稱有前面目錄限制有後面擴展名限制包含文件就會限制在該目錄了
我們來測試下如果$mod傳入這個值將會是什麼樣的結果
$mod 通過構造輸?mod=…%F…%F…%F…%Fetc%Fpasswd% 我們看結果將是
居然include(“/etc/passwd”)文件了
首先做參數過濾類型去限制用戶輸入本來就不是一個好方法一般規則是能夠做檢測的不要做替換 只要是檢測不通過的直接pass 掉!這是我們的一個原則過濾失敗情況舉不勝舉我們來看看實際過程
輸入”…/…/…/” 通過把”” 替換為””後
結果是”///” 就變成了這個了
有朋友就會說如果我直接替換為空格是不是就好了?在這個裡面確實可以替換掉但是不代表以後你都替換為空格就好了再舉例子下如有人將字符串裡面javascript替換掉代碼如下
……
$msg = str_replace(“javascript”””$msg);
看似不會出現了javascript了但是如果輸入:jjavascriptavascript 替換會替換掉中間一個變為空後前面的”j” 跟後面的會組成一個新的javascript了
其次我們看看怎麼逃脫了後面的php 限制呢用戶輸入的參數有”etc/passwd” 字符非常特殊一段連接後文件名稱變成了”……etc/passwdphp”你打印出該變量時候還是正確的但是一段放入到文件讀寫 操作方法裡面後面會自動截斷操作系統只會讀取……etc/passwd文件了 “”會出現在所有文件系統讀寫文件變量中都會同樣處理這根c語言作為字符串完整標記有關系
通過上面分析大家發現做文件類型操作時候一不注意將產生大的漏洞而且該漏洞就可能引發一系列安全問題
到這裡估計有人就會思考這個做文件讀寫操作時候如果路徑裡面有變量時候我該怎麼樣做呢?有人會說替換可以嗎? “可以”但是這個方法替換不嚴格將會出現很多問題而且對於初寫朋友也很難杜絕 做正確的事情選擇了正確的方法會從本身杜絕問題出現可能了 這裡我建議對於變量做白名單限制
- 什麼是白名單限制
舉例來說
$mod = isset($_GET[m])?trim($_GET[m]):’index’; ///讀取模塊名稱後
mod變量值范圍如果是枚舉類型那麼
if(!in_array($modarray(‘user’’index’’add’’edit’))) exit(‘err!!!’);
完全限定了$mod只能在這個數組中夠狠!!!!
- 怎麼做白名單限制
通過剛才例子我們知道如果是枚舉類型直接將值放到list中即可但是有些時候這樣不夠方面我們還有另外一個白名單限制方法就是限制字符范圍
舉例來說
$mod = isset($_GET[m])?trim($_GET[m]):’index’; ///讀取模塊名稱後
我限制知道$mod是個目錄名稱對於一般站點來說就是字母加數字下劃線之類
if(!preg_match(“/^w+$/”$mod)) exit(‘err!!!’);
字符只能是[AZaz_] 這些了夠狠!!!
總結是不是發現白名單限制方法做起來其實很簡單你知道那個地方要什麼就對輸入檢測必須是那些而且檢測自己已知的比替換那些未知的字符是不是簡單多了 好了先到這裡正確的解決問題方法會讓文件簡單而且更安全!!歡迎交流!
From:http://tw.wingwit.com/Article/program/PHP/201311/21089.html