限制unserialize()返回数组?
有什么办法来限制PHP的unserialize()只能解析数组吗? 出于安全原因。假设在我不想调用的非序列化对象中存在一个邪恶的__unserialize()魔术方法!限制unserialize()返回数组?
有几个方法,你可以解决这个问题:
- 使用的序列化的字符串正则表达式:
Piwik修补的unserialize vulnerability具有下列检查:
if (preg_match('/^a:[0-9]+:{/', $str)
&& !preg_match('/(^|;|{|})O:\+?[0-9]+:"/', $str)
签署签名的字符串。如果您添加序列化字符串的sha1哈希值+ Cookie/POST Var的秘密。你可以确定序列化的字符串没有被操纵。
编写您自己的反序列化函数。如果您只对阵列感兴趣,则不需要反序列化。自己写一些东西或使用JSON等公认的标准。
并请忽略所有没有看到安全问题的评论。 unserialize()漏洞存在于令人难以置信的高比例PHP5应用程序中,大多数书籍和教程甚至不提及它们。
有什么办法来限制PHP的unserialize()只能解析数组吗?出于安全原因。假设在我不想调用的非序列化对象中存在一个邪恶的__unserialize()魔术方法!
不是我知道的,没有。
使用像this one这样的函数可以找出序列化值的类型,但这对您也无济于事,因为数组中的任何成员都可能是非序列化对象将触发__wakeup()
调用的对象。
您将不得不扩展该函数,以便遍历序列化字符串的所有成员而不实际序列化它。当然可能,但潜在的可笑和缓慢。
想到的唯一方法是在没有定义类的环境中调用unserialize()
。这会导致类__PHP_Incomplete_Class
的对象被破坏,然后您可以解析出来。在正常的脚本环境中,这不会对您有所帮助。
也就是说,永远不要忘记序列化对象将永远不会包含任何代码。类定义必须通过其他方式存在于您的代码库中。
鉴于此,我不确定在什么情况下这首先会成为安全问题。如果您的代码库中存在恶意代码,那么将有很多机会执行它,而不必反序列化任何内容,对吗?
好的答案,完全忘了'serialize()'是如何工作的。 – 2010-10-06 17:40:12
危险的类将有一个__wakeup()方法,用于消除对象的某个属性并... – 2010-10-06 18:29:04
而且我们有一个庞大的类库和一个自动加载器,因此,很难确定应用程序启动时不会发生任何恶意行为!虽然系统只接受一个完全加密的字符串,但只有应用程序本身才能看到该字符串,但仍然不满意我放置我的确认图层的位置! – 2010-10-06 18:38:10
哇,谢谢你!我开始认为我正在变成一个偏执的程序员!那么我不能使用JSON或其他任何因为我需要反序列化()的速度。有趣的是,序列化的值永远不会在客户端/服务器之间传递。它存储在我们的安全数据库中,它是加密的,并且还有散列和盐以及所有内容。但我不需要相信数据库。我的意思是,如果我们的一个db节点被搞砸了,我不希望看到我的整个应用程序与它一起下去。所有的图层和组件必须拥有自己的安全措施! – 2010-10-06 21:46:49
这个答案给出了为什么它是必要的细节:http://*.com/questions/22433167 – NoBugs 2014-03-17 20:57:42