您當(dāng)前所在位置:
首頁(yè) →
數(shù)據(jù)庫(kù) →
MYSQL →
MySQL二次漏洞的簡(jiǎn)單防范
MySQL二次漏洞的簡(jiǎn)單防范
時(shí)間:2015-06-28 00:00:00
來(lái)源:IT貓撲網(wǎng)
作者:網(wǎng)管聯(lián)盟
我要評(píng)論(0)
- 一、提出問(wèn)題
眾所周知,數(shù)據(jù)庫(kù)操作中對(duì)于一些特殊字符(例如單引號(hào)"'"、反斜線"\"等元字符)有著嚴(yán)格的限制,如果向數(shù)據(jù)庫(kù)中寫(xiě)入的數(shù)據(jù)含有這樣的特殊字符,操作將會(huì)帶來(lái)不安全因素。所以對(duì)于用戶輸入的數(shù)據(jù),我們完全認(rèn)為它是沒(méi)有安全性的,需要在程序中對(duì)其進(jìn)行適當(dāng)?shù)倪^(guò)濾處理后,方可寫(xiě)入數(shù)據(jù)庫(kù)。
對(duì)于這點(diǎn),相信大多數(shù)PHP程序員都會(huì)注意到,一般采取的方法是使用AddSlashes()字符串函數(shù)對(duì)用戶輸入的數(shù)據(jù)進(jìn)行處理,把數(shù)據(jù)中的特殊字符加上反斜線進(jìn)行轉(zhuǎn)譯。這樣對(duì)于一般的數(shù)據(jù)庫(kù)寫(xiě)入是正常的,并不會(huì)帶來(lái)什么問(wèn)題,而問(wèn)題來(lái)源于之后的取出操作。對(duì)于前面用AddSlashes()函數(shù)進(jìn)行轉(zhuǎn)譯后保存在數(shù)據(jù)庫(kù)中的數(shù)據(jù),經(jīng)過(guò)查看數(shù)據(jù)庫(kù)我們發(fā)現(xiàn)里面存儲(chǔ)的是原始的數(shù)據(jù),也就是說(shuō)其中的特殊字符并沒(méi)有被加上反斜線。此時(shí)當(dāng)數(shù)據(jù)來(lái)源于這時(shí)的數(shù)據(jù)庫(kù)本身時(shí),安全問(wèn)題仍然存在,這就造成了二次漏洞。
流程描述 原始的數(shù)據(jù),如"'"=> 程序處理(安全的數(shù)據(jù)如"\'" )=> MySQL里存
儲(chǔ)(原始的數(shù)據(jù)如"'") => 程序處理(處理的是"'")=> 產(chǎn)生危險(xiǎn)
二、分析問(wèn)題
因此在進(jìn)行數(shù)據(jù)過(guò)濾的時(shí)候,不要只是暫時(shí)地讓數(shù)據(jù)失去危害,可以考慮永久地讓數(shù)據(jù)失去危害,譬如在過(guò)濾的時(shí)候不是將"'"變成"\'"等,而是在條件允許的情況下將其直接轉(zhuǎn)換成HTML字符"'",這樣并不影響顯示但是數(shù)據(jù)卻不再會(huì)包含讓數(shù)據(jù)庫(kù)的元字符,所以不用擔(dān)心注入漏洞了,其他的字符可以一樣考慮處理。
三、解決問(wèn)題
????為解決此問(wèn)題,我們可以用str_replace()函數(shù)依次對(duì)必要的特殊字符進(jìn)行替換。此時(shí)要注意替換后的字符串長(zhǎng)度將會(huì)改變,每替換一個(gè)字符,字符串長(zhǎng)度將會(huì)增加5。我們還需在寫(xiě)入數(shù)據(jù)庫(kù)之前判斷它是否超過(guò)字段大小。
五、演示代碼
File:test.php
代碼:
/*
*?? 二次漏洞簡(jiǎn)單檢測(cè)
*?? Author Linvo
*?? Build 2007-11-8
*/
/*
*?? 鏈接數(shù)據(jù)庫(kù)(根據(jù)情況自己修改)
*/
$Host = 'localhost';
$User = 'root';
$Pass = 'password';
$DB = 'test'; //測(cè)試庫(kù)名
$db = @mysql_connect($Host,$User,$Pass);
if(!$db)????die("連接服務(wù)器MySQL出錯(cuò)!");
else????if(!mysql_select_db($DB,$db))?? die("連接數(shù)據(jù)庫(kù)出錯(cuò)!");
define(INPUT_MAX_LENGTH, 10);?? //前臺(tái)maxlength值(初步檢測(cè))
define(INDB_MAX_LENGTH, 20);????//數(shù)據(jù)庫(kù)中字段設(shè)置的大小值(用于寫(xiě)入前的必要安全測(cè)試)
#p#副標(biāo)題#e#
/*
*?? 原始數(shù)據(jù)(如用戶輸入等)
*/
$string = "’\\"; //用戶輸入內(nèi)容
if(strlen($string) > INPUT_MAX_LENGTH) //初步檢測(cè)
????die("輸入內(nèi)容超長(zhǎng)");
echo "輸入的內(nèi)容:".$string;
/*
*?? 過(guò)濾方案
*/
//$string_in1 = AddSlashes($string); //方案一:臨時(shí)失去危險(xiǎn),但有二次漏洞
$string_in1 = str_slashes($string); //方案二:永久性失去危險(xiǎn)!(自定義函數(shù))
/*
*?? 安全測(cè)試
*/
$string_in2 = test_db($string_in1, 1); //一次漏洞檢測(cè)
$string_in3 = test_db($string_in2, 2); //二次漏洞檢測(cè)
/*
*?? 數(shù)據(jù)庫(kù)操作(函數(shù))
*/
function test_db($str_in, $time)
{
????echo "第 $time 次要寫(xiě)入的內(nèi)容:".$str_in;
????if(strlen($str_in) > INDB_MAX_LENGTH) die("第 $time 次寫(xiě)入數(shù)據(jù)超長(zhǎng)!");//必要安全測(cè)試!
????$result = mysql_query("INSERT INTO str(str) VALUES('$str_in')"); //寫(xiě)入
????if(!$result)
????{
??die("第 $time 次寫(xiě)入數(shù)據(jù)庫(kù)失敗");
????}
????echo "第 $time 次寫(xiě)入完畢";
????$result = mysql_query("SELECT str FROM str ORDER BY id DESC LIMIT 1");//取出
????if($item = mysql_fetch_array($result))
????{
??$str_out = $item['str'];
????}
????echo "第 $time 次輸出:".$str_out."";
????return $str_out;
}
/*
*?? 永久性過(guò)濾危險(xiǎn)字符
*/
function str_slashes($str)
{
????$str = str_replace("'","'",$str); //轉(zhuǎn)譯 '
????$str = str_replace("\\","\",$str); //轉(zhuǎn)譯 \
????return $str;
}
?>關(guān)鍵詞標(biāo)簽:MySQL,漏洞防范
相關(guān)閱讀
熱門(mén)文章
Xbox Game Pass
10款MySQL數(shù)據(jù)庫(kù)客戶端圖形界面管理工具推薦
MySQL常用維護(hù)管理工具
MySQL數(shù)據(jù)庫(kù)啟動(dòng)失敗1067進(jìn)程意外終止的解決辦法總結(jié)
人氣排行
10款MySQL數(shù)據(jù)庫(kù)客戶端圖形界面管理工具推薦
MySQL數(shù)據(jù)庫(kù)啟動(dòng)失敗1067進(jìn)程意外終止的解決辦法總結(jié)
Mysql 1045錯(cuò)誤解決辦法
MySQL服務(wù)器進(jìn)程CPU占用100%解決辦法
MySQL導(dǎo)出導(dǎo)入命令的用例
MySQL連接字符串的實(shí)際操作步驟匯總
MySQL無(wú)法啟動(dòng)、無(wú)法停止各種解決方法總結(jié)
三種常用的MySQL建表語(yǔ)句