|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #79031 Session unserialization problem
Submitted: 2019-12-25 09:52 UTC Modified: 2019-12-30 11:29 UTC
Avg. Score:5.0 ± 0.0
Reproduced:2 of 2 (100.0%)
Same Version:2 (100.0%)
Same OS:0 (0.0%)
From: syberon at gmail dot com Assigned: nikic (profile)
Status: Closed Package: Session related
PHP Version: 7.4.1 OS: Windows 10 1909
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please !
Your email address:
Solve the problem:
14 - 14 = ?
Subscribe to this entry?

 [2019-12-25 09:52 UTC] syberon at gmail dot com
Since version 7.4 of PHP the unserialize function can't process object references from serialized session strings.

For example, i have a few object stored in session with 3 namespaces (i exploded it to readability:




Second namespace 'MtCms\User\Authentication\Adapter\DatabaseAdapter' has object of class 'Zend\Stdlib\ArrayObject' that has a property with name 'storage' that contains anothe object.

Third namespace 'Zend_Auth' has the object of class 'Zend\Stdlib\ArrayObject' too. And this object has the same property 'storage' but it has value r:20 (reference to object of second namespace)

PHP 7.3 parses this serialized session data without any problems and at result we have a objects from 2nd and 3rd namespaces with property 'storage' what have identically object contain in.

But then i upgraded to PHP 7.4 the session_start() function give the error when trying to parse this session data. It can not recognize 'r:20' reference in object of 3rd namespace.


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2019-12-27 04:12 UTC] syberon at gmail dot com
-Package: Class/Object related +Package: Session related
 [2019-12-27 04:12 UTC] syberon at gmail dot com
I found that this problem is related to PHP 7.4 session unserializing. I made some tests and found that if some class (Zend\Stdlib\ArrayObject in my case) implements Serializable interface and has some property (object of stdClass for example) it failed to decode if stored in session.

I made a minimal reproducible example:

class SerializableClass implements Serializable {
    public $sharedProp;
    public function __construct($prop)
        $this->sharedProp = $prop;
    public function __set($key, $value)
        $this->$key = $value;
    public function serialize()
        return serialize(get_object_vars($this));
    public function unserialize($data)
        $ar = unserialize($data);
        foreach ($ar as $k => $v) {
            $this->__set($k, $v);

// Shared object that acts as property of two another objects stored in session
$testPropertyObj = new stdClass();
$testPropertyObj->name = 'test';

// Two instances of \SerializableClass that shares property
$sessionObject = [
    'obj1' => new SerializableClass($testPropertyObj),
    'obj2' => new SerializableClass($testPropertyObj),
$_SESSION = $sessionObject;

On first run it creates array with two instances of object with one shared property and store it in session.
On second run it tries to start session and fail to parse the second object stored in session because the it loses reference to property 'name'.

This script runs without any problems on PHP 7.3, and rises the parse errors on PHP 7.4.
 [2019-12-27 08:20 UTC] syberon at gmail dot com
From observable behavior it appears that unserialize implementation when called by session extension C code does not set context for unserialize, resulting in relative numbered references being wrong when used in nested unserialize calls.
 [2019-12-27 09:24 UTC] aleksey at xerkus dot pro This slightly modified example from comment above showcases the issue This example uses `php_serialize` session serializer and exhibits exactly the same behavior.
 [2019-12-27 16:53 UTC]
-Status: Open +Status: Verified -Assigned To: +Assigned To: nikic
 [2019-12-27 16:53 UTC]
This regression has apparently been introduced with commit
b8ef7c3[1].  Nikita, could you have a look please?

[1] <;a=commit;h=b8ef7c35abd31666d9fb317db4b09a9eef0ede6c>
 [2019-12-30 10:21 UTC]
Looks like this is a general bug in how serialization locking is handled. Here's a case without using sessions: The inner objects should be the same, but they're different.
 [2019-12-30 11:29 UTC]
-Status: Verified +Status: Closed
 [2019-12-30 11:29 UTC]
The commit is reverted for 7.4, so I'm closing this issue as fixed.

I've also prepared a fix for the underlying problem targeting PHP 8 here:
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Jul 17 23:01:28 2024 UTC