php - 序列化和反序列化 $_POST 数组是否安全?

标签 php security post serialization deserialization

TLDR:将 $_POST 数组序列化到文件,然后根据不同的请求或不同的脚本将其读回 $_POST 变量是否安全?

我意识到这很不寻常。这是有原因的,需要十几页的文字来解释为什么我考虑在特殊情况下这样做,至少在同一时间。

归结过程:

file_put_contents('sample.post', serialize($_POST));

$_POST = unserialize(file_get_contents('sample.post'));

我已经对 post 变量的实际内容进行了广泛的过滤。我的问题是序列化和反序列化整个 $_POST 数组的过程是否为恶意用户提供了攻击方法。

PHP 文档说“警告。不要将不受信任的用户输入传递给 unserialize()。反序列化可能会导致由于对象实例化和自动加载而加载和执行代码,恶意用户可能会利用此漏洞。”

我发现这些文章描述了这种攻击方法。但它们似乎依赖于用户能够直接指定要反序列化的字符串,即 IE unserialize($_POST['value'])。

https://www.notsosecure.com/remote-code-execution-via-php-unserialize/ https://heine.familiedeelstra.com/security/unserialize

只要我进行序列化和反序列化,就无法在反序列化过程中创建对象,对吗?

我的印象是 $_POST 数组只包含字符串(尽管我找不到 PHP 文档中明确提到的内容)。

据我了解,即使有人提供与序列化对象的格式匹配的字符串,它也会在序列化过程中以显式长度(字节长度)“存储”为字符串。所以反序列化时它只会被分配为字符串。似乎由于字符串的长度在序列化过程中与它们一起存储,因此您无法像使用 SQL 注入(inject)那样从输入中破坏序列化字符串的结构。我尝试用一​​些无效的多字节字符来欺骗它,但没有成功。然而,我无法做到这一点和经验丰富的黑客能够做到这一点是两件不同的事情。

我找不到任何有关其他攻击方法的信息。

如果我遗漏了什么,请告诉我!我刚刚读到一些评论说“你永远不应该这样做”,所以我很紧张,因为我误解了某些东西。

最佳答案

我认为,如果没有进一步的攻击,就不可能将某些内容作为 POST 变量发送,以便稍后在您的场景中利用 unserialize() 调用,但其他人可能有一个想法。如果 $_POST 有不可序列化的东西,这可能是一个问题,但我认为这可能不会发生。无论 $_POST 中的内容是什么,它都已经在内存中一次了,因此假设 serialize()unserialize() 工作正常,那么执行类似的操作应该是安全的

$serialized = serialize($userinput);
unserialize($serialized);

但是,您正在将此数据保存到磁盘上。在利用不同的缺陷并访问您的文件(或“按设计”访问,如 IT 运营人员)后,攻击者可能能够修改保存的序列化数据,并可能在那里注入(inject)攻击。这样它显然会很容易受到攻击。

所以这确实是一种风险,尽管可能不是很高。请注意,此解决方案的安全性在很大程度上取决于您保存的序列化内容的安全性。

关于php - 序列化和反序列化 $_POST 数组是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40700734/

相关文章:

javascript - 有没有办法让span标签执行PHP查询?

php - 检查安全 cookie 并在 HTTPS 模式内重定向非 HTTPS 父级

security - svn 的 SSL 协商失败

rest - 从 POST 请求返回视频

javascript - 使用 PHP 解析 CSS 文件

php - PHP 变量中的 HTML

post - s3 预签名 POST 中未强制执行内容类型

jquery - 当 jQuery.post() 请求时,Django View 不会重定向

PHP 检索 PostGIS 地理类型

windows - CryptGetProvParam 和多线程程序