You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: src/pentesting-web/deserialization/README.md
+60Lines changed: 60 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -119,6 +119,64 @@ $o->param = "PARAM";
119
119
$ser=serialize($o);
120
120
```
121
121
122
+
### Preventing PHP Object Injection with `allowed_classes`
123
+
124
+
> [!INFO]
125
+
> Support for the **second argument** of `unserialize()` (the `$options` array) was added in **PHP 7.0**. On older versions the function only accepts the serialized string, making it impossible to restrict which classes may be instantiated.
126
+
127
+
`unserialize()` will **instantiate every class** it finds inside the serialized stream unless told otherwise. Since PHP 7 the behaviour can be restricted with the [`allowed_classes`](https://www.php.net/manual/en/function.unserialize.php) option:
If **`allowed_classes` is omitted _or_ the code runs on PHP < 7.0**, the call becomes **dangerous** as an attacker can craft a payload that abuses magic methods such as `__wakeup()` or `__destruct()` to achieve Remote Code Execution (RCE).
145
+
146
+
#### Real-world example: Everest Forms (WordPress) CVE-2025-52709
147
+
148
+
The WordPress plugin **Everest Forms ≤ 3.2.2** tried to be defensive with a helper wrapper but forgot about legacy PHP versions:
149
+
150
+
```php
151
+
function evf_maybe_unserialize($data, $options = array()) {
152
+
if (is_serialized($data)) {
153
+
if (version_compare(PHP_VERSION, '7.1.0', '>=')) {
On servers that still ran **PHP ≤ 7.0** this second branch led to a classic **PHP Object Injection** when an administrator opened a malicious form submission. A minimal exploit payload could look like:
0 commit comments