在網(wǎng)站開(kāi)發(fā)過(guò)程中,為了方便對(duì)數(shù)組的使用,經(jīng)常會(huì)用到PHP語(yǔ)言提供的extract函數(shù)來(lái)將一個(gè)數(shù)組拆分成單獨(dú)的變量,但是這個(gè)函數(shù)卻存在極為嚴(yán)重的安全漏洞,可能會(huì)造成代碼注入、變量覆蓋等風(fēng)險(xiǎn)。
extract函數(shù)的工作原理是將數(shù)組中的鍵名作為變量名,鍵值作為變量的值,這意味著如果數(shù)組中包含可通過(guò)用戶控制的變量名時(shí),就存在代碼注入的危險(xiǎn)。
// 使用 extract 函數(shù) $param = $_GET['param']; extract($param);
例如,在上面這個(gè)例子中,如果用戶輸入的param值中包含了“_SESSION”或“_COOKIE”等變量名,在變量解析時(shí)就會(huì)將其作為當(dāng)前腳本中的變量,導(dǎo)致用戶提權(quán)、注入惡意代碼等安全問(wèn)題。
除此之外,extract函數(shù)還有可能會(huì)覆蓋已有的變量,引發(fā)意料之外的錯(cuò)誤。
// 當(dāng)存在 $a 變量時(shí),將會(huì)被覆蓋 $param = array('a'=>1, 'b'=>2); extract($param); echo $a; // 輸出 1
出現(xiàn)這種問(wèn)題的原因在于,extract函數(shù)在變量名與數(shù)組鍵名相同時(shí),會(huì)將已有變量的值替換為數(shù)組的值。
為了避免extract漏洞帶來(lái)的風(fēng)險(xiǎn),可以采取以下幾種措施:
1.禁止使用extract函數(shù)。
對(duì)于已有的代碼,可以通過(guò)搜索extract函數(shù)并手動(dòng)重構(gòu)來(lái)消除漏洞。
2.限制可用數(shù)組。
可以通過(guò)白名單的方式,只允許某些數(shù)組進(jìn)行解析,或限制解析的數(shù)組中只包含特定的鍵名。例如:
// 只解析特定的數(shù)組鍵名 $param = array_intersect_key($_GET, array('a'=>1, 'b'=>1)); extract($param);
3.對(duì)傳入的值進(jìn)行過(guò)濾。
可以對(duì)提取出的變量進(jìn)行安全過(guò)濾,例如使用htmlspecialchars函數(shù)防止XSS漏洞。
// 過(guò)濾輸入的變量值 $param = $_GET['param']; $param = array_map('htmlspecialchars', $param); extract($param);
總之,在開(kāi)發(fā)過(guò)程中,我們需要時(shí)刻意識(shí)到代碼安全的重要性,并以保護(hù)用戶隱私、防范黑客攻擊為出發(fā)點(diǎn),努力編寫(xiě)安全、可靠的代碼。