關(guān)于PHP is_a()漏洞的問(wèn)題現(xiàn)在已經(jīng)引起了廣泛的關(guān)注。在PHP 5.3.x之前的版本中,is_a()函數(shù)采用了一種不安全的實(shí)現(xiàn)方式,可能會(huì)導(dǎo)致遠(yuǎn)程代碼執(zhí)行。以下是一些關(guān)于此漏洞的實(shí)際案例:
class foo {
private $bar = "Hello World!";
}
class bar {
function __construct() {
$this->input = $_GET['input'];
}
}
$class = new foo();
if (is_a($class, $_GET['input'])) {
new bar();
}
上述代碼中,$_GET['input']的值是任意提供的輸入。如果攻擊者指定了一個(gè)不是類(lèi)名的輸入,is_a()函數(shù)將調(diào)用__autoload()函數(shù)嘗試加載類(lèi)。攻擊者可以利用這種方法執(zhí)行遠(yuǎn)程代碼,例如指定一個(gè)像"http://attacker.com/teapot.class.php"這樣的輸入來(lái)加載來(lái)自攻擊者服務(wù)器的惡意代碼。
解決這個(gè)問(wèn)題的方法很簡(jiǎn)單,就是確保輸入的值是一個(gè)合法的類(lèi)名,而不是在這個(gè)字符串中包含URL或其他危險(xiǎn)的字符。下面是代碼的修復(fù)版本:
class foo {
private $bar = "Hello World!";
}
class bar {
function __construct() {
$this->input = $_GET['input'];
}
}
$class = new foo();
if (is_a($class, 'foo')) {
new bar();
}
修復(fù)的代碼中,is_a()函數(shù)使用了字符串'foo'作為參數(shù),而不是來(lái)自用戶(hù)輸入的變量。這樣可以確保在is_a()函數(shù)調(diào)用(沒(méi)有調(diào)用__autoload())之前,輸入的字符串已經(jīng)處理過(guò)了,不會(huì)包含任何惡意代碼或URL。
總之,在處理用戶(hù)輸入時(shí),一定要牢記安全性的問(wèn)題,避免使用用戶(hù)輸入處理函數(shù)或者不必要的函數(shù)和調(diào)用,以避免不必要的風(fēng)險(xiǎn)和損失。