TLDR:将$ _POST数组序列化到文件然后将其读回到不同请求或不同脚本上的$ _POST变量是否安全?
我意识到这很不寻常。这是有原因的,并且需要十几页的文字来解释为什么我考虑在特殊情况下这样做,至少在此期间。
煮沸过程:
file_put_contents('sample.post', serialize($_POST));
$_POST = unserialize(file_get_contents('sample.post'));
我已经对post变量的实际内容进行了广泛的过滤。我的问题是序列化和反序列化整个$ _POST数组的过程是否给恶意用户一种攻击方法。
PHP文档说“警告。不要将不受信任的用户输入传递给unserialize()。反序列化可能导致代码被加载和执行,因为对象实例化和自动加载,恶意用户可能能够利用它。”< / p>
我发现这些文章描述了这种攻击方法。但它们似乎依赖于用户能够直接指定要反序列化的字符串,IE unserialize($ _ POST ['value'])。
https://www.notsosecure.com/remote-code-execution-via-php-unserialize/ https://heine.familiedeelstra.com/security/unserialize
我是否正确,只要我序列化和反序列化,就无法在反序列化过程中创建对象,对吧?
我的印象是$ _POST数组只会包含字符串(虽然我找不到PHP文档中明确提到的内容)。
据我了解,即使有人提供了与序列化对象格式匹配的字符串,它也会在序列化期间“存储”为字符串,并具有明确的长度(字节长度)。因此,在反序列化时它将被指定为字符串。看起来因为字符串的长度在序列化期间与它们一起存储,所以你不能像输入SQL一样破坏输入中的序列化字符串的结构。我试图用一些无效的多字节字符欺骗它,但没有运气。但是,我无法做到这一点,经验丰富的黑客能够做到这一点是两件事。
我找不到其他任何关于其他攻击方法的内容。
如果我错过了什么,请告诉我!我刚看了好几条评论说“你永远不应该这样做”,所以我很担心我误会了什么。
答案 0 :(得分:0)
我认为没有进一步的攻击是不可能发送一些东西作为POST变量来在你的场景中稍后利用unserialize()
调用,但其他人可能有一个想法。如果$ _POST有一些不可序列的东西可能会有问题,但我认为这可能不会发生。无论$ _POST中是什么,它已经在内存中了一次,所以假设serialize()
和unserialize()
正常工作,那么做
$serialized = serialize($userinput);
unserialize($serialized);
但是,您要将此数据保存到中间的磁盘中。利用不同的漏洞并访问您的文件(或访问&#34;设计&#34;,像IT操作人员),攻击者可能能够修改已保存的序列化数据,并可能在那里注入他的攻击。那样的话显然很脆弱。
所以这确实是一种风险,尽管可能不是很高。请注意,此解决方案的安全性在很大程度上取决于已保存的序列化内容的安全性。