PHP中序列化和反序列化

本文详细介绍了PHP中序列化和反序列化的概念及应用,包括如何将对象转化为字符串以便于存储,以及如何从存储的字符串中恢复原始数据。同时,还探讨了序列化过程中__sleep()和反序列化过程中__wakeup()这两个魔术方法的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

所谓序列化,就是将一个变量的数据转换为字符串(但是与类型转换不同)。其目的是将该字符串存储起来(存为文本文件),当在其他环境上运行时,可以通过反序列化,将其回复。(一般用在数据需要存储的地方)

序列化:

    $str=serialize($变量)//将数据转换为字符串,并存入变量$str。

    file_put_conetents("文本文件路径",$str);//将文件存在文本文件中。

反序列化:

    $str=file_get_contents("文本文件路径");//取得文件中存储的序列化的信息。

    $value=unserialize($str);//将取出的字符串内容转换为正常的数据存入$value 中。

序列化和反序列化时的魔术方法:

    __sleep():在对某个类的对象进行序列化的时候,会自动调用该类中的__sleep()方法;

                        使用该方法可以对需要进行序列化的数据进行选着,挑选出需要的属性,存入数组,该数组会在结束后返回,数组里的值就是要序列化的东西。

    __wakeup():与__sleep()正好相反,在反序列化的时候调用,可以进行一些有用的操作,以使得状态回到序列化之前的状态(如数据库连接)。因为序列化只是将需要的属性变为字符串存储起来,反序列化也只是将字符串变回数据,但是一些状态并没有返回到之前的状态,此时就可以通过__wakeup()来进行操作,回到与之前完全相同的状态。

### PHP反序列化的基本使用方法 PHP中的序列化(`serialize()`)反序列化(`d`eserialize())是用于将对象、数组等复杂数据结构转换为字符串以便存储或传输的机制。例如,一个对象可以通过 `serialize()` 转换为字符串形式,便于保存到数据库或会话文件中;当需要恢复该对象时,可以使用 `unserialize()` 将其还原为原始对象状态。 ```php class Example { public $data = "test"; } // 序列化对象 $obj = new Example(); $serialized = serialize($obj); // 输出: O:7:"Example":1:{s:4:"data";s:4:"test";} echo $serialized . "\n"; // 反序列化对象 $unserialized = unserialize($serialized); echo $unserialized->data; // 输出: test ``` ### PHP反序列化的原理 PHP在执行反序列化操作时,会根据字符串格式重建原始变量结构。序列化字符串中包含了类名、属性名及其值等信息。如果反序列化的数据被攻击者篡改,则可能触发某些危险的“魔术方法”(如 `__construct()`、`__destruct()`、`__wakeup()` 等),从而导致代码执行或其他恶意行为[^2]。 反序列化漏洞的核心在于:开发者没有对用户输入的数据进行严格的过滤验证,而直接将其作为参数传递给 `unserialize()` 函数。攻击者通过构造恶意输入,可以在反序列化过程中触发特定类的方法调用,进而实现任意代码执行或敏感信息泄露的目的[^3]。 ### PHP反序列化漏洞的常见利用方式 - **魔术方法触发**:攻击者通过构造特定的序列化字符串,使得在反序列化过程中自动调用某些魔术方法(如 `__wakeup()` 或 `__destruct()`)。这些方法内部若存在可被利用的功能(如文件操作、命令执行等),则可能导致严重后果[^1]。 - **POP链(Property Oriented Programming)**:这是一种高级利用技术,攻击者通过查找多个类之间的属性引用关系,构建出一条从入口点到目标函数的调用链路。即使没有直接暴露危险方法,也能通过间接方式达成攻击目的。 ### PHP反序列化漏洞的危害 PHP反序列化漏洞可能导致多种安全问题: - **远程代码执行(RCE)**:攻击者可通过构造恶意输入,在服务器上执行任意命令,获取系统控制权。 - **会话劫持**:由于PHP的session机制依赖于序列化/反序列化操作,因此攻击者可能伪造会话内容,冒充合法用户访问系统。 - **数据篡改与泄露**:攻击者可以修改反序列化后的对象属性,篡改业务逻辑,甚至读取数据库中的敏感信息。 ### 如何防止PHP反序列化漏洞 1. **避免反序列化不可信数据**:最根本的防护措施是不要对来自用户的输入执行 `unserialize()` 操作,除非绝对必要且已充分验证其安全性。 2. **使用 `json_encode()` `json_decode()` 替代**:相较于 `serialize()` / `unserialize()`,JSON编码/解码更安全,因为它不涉及类实例化过程。 3. **白名单校验**:如果确实需要处理用户提供的序列化数据,应限制允许反序列化的类名,并确保只接受预期类型的对象。 4. **启用 `__wakeup()` 验证机制**:在关键类中定义 `__wakeup()` 方法,检查反序列化后的对象状态是否合法。 5. **更新框架与依赖库**:及时修补第三方组件中存在的已知反序列化漏洞,防止被攻击者利用。 ### 示例:简单的PHP反序列化漏洞演示 ```php class VulnerableClass { public $cmd = "echo 'Hello, World!';"; function __wakeup() { eval($this->cmd); // 危险操作:执行任意代码 } } // 攻击者构造恶意序列化字符串 $input = 'O:14:"VulnerableClass":1:{s:3:"cmd";s:13:"system("id");";}'; unserialize($input); // 触发 __wakeup(),执行 system("id") ``` 上述代码展示了攻击者如何通过精心构造的序列化字符串,使原本仅用于输出“Hello, World!”的对象执行了 `system("id")` 命令,从而实现了远程命令执行攻击[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值