【发布时间】:2010-10-06 16:26:15
【问题描述】:
有没有办法限制 PHP 的 unserialize() 只解析数组? 出于安全原因。假设我不想调用的未序列化对象中有一个邪恶的 __unserialize() 魔术方法!
【问题讨论】:
标签: php security serialization
有没有办法限制 PHP 的 unserialize() 只解析数组? 出于安全原因。假设我不想调用的未序列化对象中有一个邪恶的 __unserialize() 魔术方法!
【问题讨论】:
标签: php security serialization
有没有办法限制 PHP 的 unserialize() 只解析数组?出于安全原因。假设我不想调用的未序列化对象中有一个邪恶的 __unserialize() 魔术方法!
我不知道,没有。
可以使用this one 之类的函数找出序列化值的类型,但这也无济于事,因为数组的任何成员都可能再次是一个对象,其反序列化将触发@987654322 @ 称呼。
您必须扩展该函数,以便它遍历序列化字符串的所有成员,而无需实际序列化它。当然可能,但可能会很笨拙且缓慢。
想到的唯一其他方法是在没有定义类的环境中调用unserialize()。这将导致__PHP_Incomplete_Class 类的对象损坏,然后您可以解析出该对象。但是,在正常的脚本环境中,这对您没有帮助。
也就是说,永远不要忘记序列化对象永远不会包含任何代码。类定义必须通过其他方式出现在您的代码库中。
有鉴于此,我不确定在什么情况下这首先可能是一个安全问题。如果您的代码库中有恶意代码,那么将有很多机会执行它而无需反序列化任何内容,不是吗?
【讨论】:
有几种方法可以解决这个问题:
Piwik 通过以下检查修补了 unserialize vulnerability:
if (preg_match('/^a:[0-9]+:{/', $str)
&& !preg_match('/(^|;|{|})O:\+?[0-9]+:"/', $str)
签署已签名的字符串。如果您将序列化字符串的 sha1 哈希 + 秘密添加到 Cookie/POST Var。您可以确定序列化的字符串没有被操纵。
编写您自己的反序列化函数。如果您只对数组感兴趣,则不需要反序列化。自己写一些东西或使用 JSON 等公认的标准。
请忽略此处未发现安全问题的所有 cmets。 unserialize() 漏洞存在于非常高比例的 PHP5 应用程序中,大多数书籍和教程甚至都没有谈论它们。
【讨论】: