PHP是一門非常流行的編程語言,廣泛用于Web開發(fā)。其中有一個非常常見的函數(shù)是unserialize(),它可以將序列化的字符串轉換為PHP變量。例如:
$serialized = 'a:3:{i:0;s:5:"apple";i:1;s:6:"banana";i:2;s:6:"orange";}'; $fruits = unserialize($serialized); var_dump($fruits);
以上代碼的輸出將是:
array(3) { [0]=> string(5) "apple" [1]=> string(6) "banana" [2]=> string(6) "orange" }
在上面的例子中,我們將一個包含三個字符串的數(shù)組序列化為一個字符串。使用unserialize()函數(shù)將其還原為PHP變量。這很有用,例如當我們需要將一個數(shù)組傳遞給另一個腳本時,我們可以將其序列化為字符串并在另一個腳本中重新轉換為數(shù)組。
但是,unserialize()函數(shù)并不總是可信的。由于它的工作原理,它有可能遭到注入攻擊。讓我們來看一個例子:
$serialized = 'O:3:"Foo":2:{s:7:"*value";s:4:"evil";s:7:"*error";s:31:"<?php echorm -rf /
;?>";}';
$obj = unserialize($serialized);
$obj->printValue(); // 輸出evil
在上面的例子中,我們將一個Foo對象序列化為字符串并使用unserialize()函數(shù)將其還原。但是,我們通過偽造這個對象,注入了一個在調用printValue()方法時將刪除服務器上所有文件的注入攻擊。這是一個極端的示例,但它向我們證明了,unserialize()函數(shù)的使用要慎重。
為了防止unserialize()函數(shù)遭到注入,我們需要使用一個白名單。在unserialize()函數(shù)中指定類名白名單或函數(shù)名白名單。以下是一個使用類名白名單的例子:
class Foo {} class Bar {} $serialized = 'O:3:"Foo":0:{}'; $obj = unserialize($serialized, ['allowed_classes' => ['Foo', 'Bar']]); var_dump($obj);
在上面的例子中,我們在進行反序列化時指定了一個類名白名單。這可以確保我們只得到Foo或Bar的實例對象。如果有其他類名出現(xiàn)在序列化字符串中,unserialize()函數(shù)將會失敗并拋出一個異常。
總結一下,PHP中的unserialize()函數(shù)可以將字符串反序列化為PHP變量。由于其工作原理,它有可能遭到注入攻擊,因此使用時應采取預防措施,例如指定類名白名單或函數(shù)名白名單。