该格式在实现之外没有规范;的 PHP 手册 unserialize() 是参考,并且明确传递不受信任的输入是不安全的。
PHP数据第一次序列化花了一个下午,那是WP Adminify支持票,一个用户's仪表板小部件设置已经走火入魔,"设置"他们描述的住在 wp_options 表作为单个序列化字符串,看起来像线路噪声: a:4:{s:8:"_builtin";b:1;...。我看不懂,一眼就看不出哪里出了问题,也不想把一个完整的PHP环境旋转起来,只是为了 print_r 1行。那天下午就是我为什么关心有一个解码器, 距离浏览器标签页只有一个。
WordPress、WooCommerce、Laravel 或任何遗留的 PHP 代码库中工作,无论你是否愿意,你都遇到了序列化数据,它会显示在选项表、会话文件、缓存存储和发布元中,当某些东西发生故障时,能够快速读取它是五分钟修复和下午之间的区别。
本指南涵盖了序列化格式的实际含义以及如何使用以下格式解码 取消序列化 toolz。dev上的工具,而且-重要的是-在信任非英语数据上的输出之前,你需要了解的一个真正的限制。
TL;博士: PHP
serialize()将值打包到输入的字符串中,例如a:2:{s:4:"name";s:5:"Alice";...}每件作品都带有其类型和长度。 取消序列化工具 在浏览器中解析它并将其显示为树,print_r、var_dump的,或者JSON-没有PHP服务器,没有数据上传,大警告我自己验证了:它计算的是UTF-16代码单元中的字符串长度,而不是字节,因此包含重音符,表情符号或CJK字符的序列化数据可能会错误解析或失败,对于ASCII数据,它可靠地读取数据;它不会解析对象引用或让你编辑到位。
PHP 序列化是什么,真的?
序列化将 PHP 值(数组、对象、字符串、整数等)转换为平坦的字符串,您可以存储在数据库列或文件中,然后使用它进行重建 unserialize().两个职能做功: serialize() 将值转换为字符串,并且 unserialize() 将其转换回来。
1旦知道代码, 格式就可读的原因是每个值都宣布它的类型和大小, 这里是整个词汇:
s:5:"hello" // string: s:length:"value"
i:42 // integer: i:value
d:3.14 // double: d:value
b:1 // boolean true (b:0 is false)
N; // null
a:2:{...} // array: a:count:{key;value;...}
O:8:"ClassName":1:{...} // object: O:namelen:"Class":propcount:{...}
所以序列化的关联数组如下所示:
a:3:{s:4:"name";s:10:"John Smith";s:5:"email";s:16:"[email protected]";s:4:"role";s:5:"admin";}
这只是这个 PHP 阵列,包装紧密:
array(
'name' => 'John Smith',
'email' => '[email protected]',
'role' => 'admin'
)
机(compact for the machine),在支持呼叫的下午2点,接近人类无法读取,这就是工具解决的整个问题。
Toolz。dev 如何取消序列化工具对其进行解码?
您粘贴字符串,它会直接在浏览器中的 JavaScript 中解析格式并渲染结果。我在编写此内容时针对工具'自己的解析器测试了这些格式。因此,下面的行为是它实际所做的,而不是手册所假设的。
顺序整数键控数组作为真实列表返回。 a:2:{i:0;s:5:"apple";i:1;s:6:"banana";} 解码为 ["apple", "banana"].关联数组作为关键对象回来嵌套结构正确嵌套,数组内部数组内部对象,一直向下。
对象保留其类名。 O:4:"User":2:{s:4:"name";s:3:"Bob";...} 用 a 解码 __class__ 的标记 "User" plus它的属性,所以类型和数据都可以看到,它甚至可以处理私有和受保护属性的尴尬情况,php在类名周围用空字节前缀进行序列化-工具剥离那些,并向您显示干净的属性名称。
您可以获得八种输出格式来切换:树视图、 print_r、 var_dump、 var_export、krumo、firephp、dbug 和普通的 JSON。我住在 Tree View 中用于探索,JSON 用于复制到其他东西,但如果您的肌肉记忆预期的话 var_dump 输出,就在那里。
您需要知道的一个限制:多字节字符串
在我信任生产数据解码器之前,我希望有人告诉我这一部分,所以这里是预先的。
PHP's 序列化格式测量字符串长度 字节.工具测量它中的 JavaScript 字符串长度的,它统计UTF-16代码单位,对于普通的ASCII来说那些是相同的数字,所以英语数据解码完美,字符串包含多字节UTF-8字符的那一刻,它们就发散了。
取 "咖啡馆。" 这个词在 UTF-8 中 " " 是两个字节,因此 PHP 将其序列化为 s:5:"café" - 长度五,计算字节。工具读取 5 并抓住五个 代码单位 从字符串中,这是 café" -吞下收盘报价失去位置我正好跑了这个:一个独立的 s:5:"café"; 解码到错误的值,并在数组内进行解码 a:2:{s:1:"a";s:5:"café";s:1:"b";i:1;} 它彻底失败了 Unknown type ':' at position 25。
实用的外卖:如果您正在调试纯 ASCII 的 WordPress 选项 - 大多数插件设置、slugs、布尔标志 - 您很好。如果序列化数据包含重音名称、表情符号或 CJK 文本,则解码可能会损坏或错误,这是工具中的真实错误,而不是您的数据。 (对于记录,我们端的修复是按 UTF-8 字节长度而不是解析 .length;它在我的列表中。)当你击中它时,WP-CLI's序列化感知命令在服务器上是可靠的后备。
有一个相关的、更温和的警告: var_dump 输出使用相同的代码单元计数报告字符串长度,因此 var_dump("café") 显示 string(4) 真正的 PHP 会说在哪里 string(5)并且表情符号显示的长度也与 PHP's 字节计数不匹配。将这些数字读作 "JavaScript 长度,"不是 "PHP 字节长度。"
PHP 之外,为什么要将数据取消序列化?
很多原因,而且几乎没有一个是"为了好玩。 "
Debugging是大, 一份bug报告说用户's设置错误;设置是数据库中一个序列化的blob;解码之前看不到问题, 我使用的工作流程是: SELECT option_value FROM wp_options WHERE option_name = 'widget_text';、复制结果,粘贴到 取消序列化工具并且读取树。十秒与编写一次性 PHP 脚本。
Migrations 是偷偷摸摸的,串行化的字符串嵌入了自己的长度,所以在数据库转储上一个天真的查找和替换 - 比如说,将旧域替换为新域 - 更改字符串内容而不更新长度前缀,每个受影响的值都变得不可解码首先向您准确显示哪些值携带域,这样您就知道简单的搜索和替换会破坏什么。 (替换本身的正确工具是 WP-CLI's search-replace的,(这就懂得了连载。)
然后是缓存和会话检查 - PHP 应用程序中的 Redis、Memcached 和文件缓存通常保存序列化值 - 以及安全审查,您需要查看实际存储的内容才能判断其是否安全。
解码浏览器中的序列化数据安全吗?
PHP中比做起来更安全,而且值得理解为什么。
PHP's原生 unserialize() security历史悠久,fed一个精心制作的字符串,它可以实例化任意对象并触发它们的魔法方法(__wakeup、 __destruct的),在正确的条件下,它会变成对象注入攻击,最坏的情况是远程代码执行。这就是为什么长期的建议是永远不要调用 unserialize() 在不受信任的输入上,并传递 ['allowed_classes' => false] 当你必须的时候。
浏览器工具回避了这一切,因为它从来没有回避过这一切 跑 PHP。读取字符串格式并显示结构- 没有创建PHP对象,没有魔法方法开火,也没有解释器可以利用,数据也留在你的设备上;它是在本地解析的,从不发送到服务器,这对于序列化的blob是会话或其他你宁愿不上传的东西来说 检查 不受信任的序列化数据,浏览器确实是更安全的地方。
本地 PHP unserialize() |
Toolz.dev 浏览器工具 | |
|---|---|---|
| 实例化对象 | 是(注射风险) | 不 - 仅读取结构 |
| 在服务器上运行 | 是的 | 否 - 浏览器本地 |
| 不受信任的输入是安全的 | 仅限 allowed_classes |
是的,它永远不会执行 |
| 处理多字节长度 | 正(字节) | 不可靠(代码单位) |
| 解析对象引用 | 是的 | 没有-显示 [Reference] |
| 目的 | 重建实时值 | 检查并阅读 |
该表也是权衡的诚实总结:浏览器工具是安全的阅读器,而不是语言功能的直接替代品。
现实世界中常见的来源是什么?
如果你在这里,那可能是其中之一。WordPress 非常依赖序列化 wp_options - widget_text、 sidebars_widgets、 theme_mods_*、活动插件列表、cron 调度表 WooCommerce 将产品变体、属性、自定义字段存储为序列化的帖子元,这就是为什么定价错误的产品如此频繁地追溯到序列化的值 Laravel 使用序列化进行文件缓存和会话存储 Magento's 配置系统充满了到处相同的格式;相同的解码方法。
该工具不做的一些事情
2个诚实的边界。它不解析引用- PHP可以序列化指向更早值的指针(r: 或 R:),并且该工具将这些显示为字面意思 [Reference] marker而不是跟随它们。而且它是一个阅读器,而不是编辑器:没有"更改此值并重新序列化"模式。要修改序列化数据,请对其进行解码,在php或json中进行更改,并在php侧重新序列化。如果您必须手动编辑原始字符串,请记住您也必须固定长度前缀,并且 - 根据上面的部分 - 计算字节,而不是字符。
常见问题
PHP序列化是干什么用的?
它将数组和对象等复杂值转换为单个字符串,可以驻留在数据库列、文件或缓存中,并在以后重建。 WordPress、WooCommerce、Laravel 和 Magento 都大量使用它来设置、会话数据和缓存值。
PHP 服务器的情况下,我可以取消序列化 PHP 数据吗?
是的。 取消序列化工具 在浏览器中解析 JavaScript 中的序列化 PHP。没有安装 PHP,没有服务器,没有帐户。
解码浏览器中的序列化数据安全吗?
是的,它比 PHP's 自己的更安全 unserialize() on 不信任的输入,因为工具只读取字符串结构,它从不实例化 PHP 对象,所以使原生的魔法方法攻击 unserialize() 危险根本不可能发生。
为什么我的序列化字符串无法解码?
件(你错过了尾部大括号或第一个字符)、查找和替换后的一个断裂的长度前缀,或者实际上没有PHP序列化的数据,通常的原因还有一个能抓住人的:如果字符串包含重音字符、表情符号或CJK文本,工具's代码单元长度计数可能会错误解析它,因为PHP以字节计数字符串长度,工具计数UTF-16单元。
我可以用它解码 WordPress wp_options 值吗?
是的 - 这是最常见的用途之一。查询 option_value、粘贴进去,然后读取结构,只要注意,如果选项中包含多字节文本,则可能需要在服务器上进行 WP-CLI 替代。
我可以使用此工具编辑序列化数据吗?
No,它是读取器,要改变一个值,解码,用PHP或者JSON编辑,在PHP端重新序列化,手工编辑raw字符串就是自己固定字节长度前缀,容易出错。
PHP 序列化与 JSON 有什么区别?
Serialization 保留了 PHP 特定的类型,包括对象类名称和私有属性,JSON 与语言无关,只知道字符串、数字、布尔值、空、数组和对象,新代码通常更喜欢 JSON,因为 json_decode() doesnot 实例化对象,因此避免了注入风险,而且 JSON 到处都是可读的,你可以将一个解码的结构移动到 json格式化程序 以这种方式处理它。
该工具是否处理序列化对象,而不仅仅是数组?
是对象解码时,其类名与属性一起保存,私有或受保护的属性(PHP 序列化为空字节前缀)被清理为输出中的可读名称。
结论
如果您触摸 WordPress、WooCommerce 或 Laravel,并且能够按需阅读,则串行化的 PHP 数据是不可避免的,这会将一类令人沮丧的错误变成快速的错误 取消序列化工具 php服务器的情况下,在浏览器选项卡中做到这一点,安全,无需php服务器- 只要你知道它的一个真实边缘:多字节字符串可以跳闸长度计数,ASCII数据是它发光的地方粘贴,读取,修复。并且当数据充满重音或表情符号时,可以触及WP-CLI代替。
相关工具:



