有没有办法限制PHP的unserialize()只解析数组? 出于安全考虑。假设在我不想调用的反序列化对象中有一个邪恶的__unserialize()魔术方法!
答案 0 :(得分:5)
有没有办法限制PHP的unserialize()只解析数组?出于安全考虑。假设在我不想调用的反序列化对象中有一个邪恶的__unserialize()魔术方法!
不是我知道的,不。
可以使用类似this one之类的函数找出序列化值的类型,但这也无济于事,因为数组的任何成员都可能再次成为反序列化将触发的对象__wakeup()
致电。
您必须扩展该函数,以便遍历序列化字符串的所有成员,而无需实际序列化它。当然可能,但可能是kludgy和慢。
唯一想到的另一种方法是在没有定义类的环境中进行unserialize()
调用。这将导致类__PHP_Incomplete_Class
的对象损坏,然后您可以解析它。在普通的脚本环境中,这对您没有帮助。
尽管如此,永远不要忘记序列化对象永远不会包含任何代码。类定义必须通过其他方式存在于您的代码库中。
鉴于此,我不确定在什么情况下这可能是一个安全问题。如果你的代码库中有恶意代码,那么就有很多机会执行它而不必反序列化任何东西,不是吗?
答案 1 :(得分:4)
有几种方法可以解决这个问题:
Piwik使用以下检查修补unserialize vulnerability:
if (preg_match('/^a:[0-9]+:{/', $str)
&& !preg_match('/(^|;|{|})O:\+?[0-9]+:"/', $str)
签名已签名的字符串。如果您将序列化字符串的sha1哈希值+一个秘密添加到Cookie / POST Var。您可以确定不会操纵序列化字符串。
编写自己的反序列化函数。如果您只对Arrays感兴趣,则不需要反序列化。自己写一些东西或使用像JSON等公认的标准。
请忽略所有未发现安全问题的评论。 unserialize()漏洞存在于令人难以置信的高比例PHP5应用程序中,大多数书籍和教程甚至都没有谈论它们。