uuid icon indicating copy to clipboard operation
uuid copied to clipboard

__unserialize() fails for existing sessions

Open JohJohan opened this issue 2 years ago • 1 comments

__unserialize() fails for existing user sessions because 'bytes' isn't set.

Description

We get the following error:

ValueError: Ramsey\Uuid\Uuid::__unserialize(): Argument #1 ($data) is invalid #15 /vendor/ramsey/uuid/src/Uuid.php(333): Ramsey\Uuid\Uuid::__unserialize #14 [internal](0): unserialize #13 /vendor/symfony/security-http/Firewall/ContextListener.php(312): Symfony\Component\Security\Http\Firewall\ContextListener::safelyUnserialize #12 /vendor/symfony/security-http/Firewall/ContextListener.php(126): Symfony\Component\Security\Http\Firewall\ContextListener::authenticate #11 /vendor/symfony/security-http/Firewall/AbstractListener.php(26): Symfony\Component\Security\Http\Firewall\AbstractListener::__invoke #10 /vendor/symfony/security-http/Firewall.php(119): Symfony\Component\Security\Http\Firewall::callListeners #9 /vendor/symfony/security-http/Firewall.php(92): Symfony\Component\Security\Http\Firewall::onKernelRequest #8 /vendor/symfony/event-dispatcher/EventDispatcher.php(270): Symfony\Component\EventDispatcher\EventDispatcher::Symfony\Component\EventDispatcher\{closure} #7 /vendor/symfony/event-dispatcher/EventDispatcher.php(230): Symfony\Component\EventDispatcher\EventDispatcher::callListeners #6 /vendor/symfony/event-dispatcher/EventDispatcher.php(59): Symfony\Component\EventDispatcher\EventDispatcher::dispatch #5 /vendor/symfony/http-kernel/HttpKernel.php(128): Symfony\Component\HttpKernel\HttpKernel::handleRaw #4 /vendor/symfony/http-kernel/HttpKernel.php(74): Symfony\Component\HttpKernel\HttpKernel::handle #3 /vendor/symfony/http-kernel/Kernel.php(202): Symfony\Component\HttpKernel\Kernel::handle #2 /vendor/symfony/runtime/Runner/Symfony/HttpKernelRunner.php(35): Symfony\Component\Runtime\Runner\Symfony\HttpKernelRunner::run #1 /vendor/autoload_runtime.php(35): require_once #0 /public/index.php(18): null

In our Symfony 5 application we got that error after upgrading to Ramsey/UUID 4 for sessions that where still logged in. It is because off https://github.com/ramsey/uuid/commit/0997de99a2a2ce27f6b5a913dcb26442ab61a6c8 is this error expected? As it is a major update from 3.x to 4.x, if that is the case I don't see this mentioned in the changelog. 

For us this means we have to logout every user who is logged in now. So that they won't encounter this error

Steps to reproduce

1: Symfony 5 installation with security and logged in user and Ramsey/UUID 3.x 2: upgrade Ramsey/UUID to 4.x 3. See error for __unserialize()

Environment details

  • PHP version: we are using 8.0

JohJohan avatar Feb 15 '22 18:02 JohJohan

Step 1 seems like a very big step. What are all the steps involved in getting step 1 set up?

ramsey avatar Aug 05 '22 17:08 ramsey

Objects serialized in one version will usually not be compatible with another. This isn't restricted to major versions, an object from 4.0.0 will not work on 4.5.1. This behavior technically doesn't break the public api, but I think it's worth mentioning it in the documentation.

Example:

$guidBytes = \hex2bin('0eab93fc9ec9584b975e9c5e68c53624');

$featureSet = new Ramsey\Uuid\FeatureSet(true);
$factory = new Ramsey\Uuid\UuidFactory($featureSet);

$guid = $factory->fromBytes($guidBytes);

echo \serialize($guid);

With version 3.9.6:

O:16:"Ramsey\Uuid\Uuid":1:{s:6:"string";s:36:"fc93ab0e-c99e-4b58-975e-9c5e68c53624";}

With version 4.0.0:

C:21:"Ramsey\Uuid\Guid\Guid":36:{fc93ab0e-c99e-4b58-975e-9c5e68c53624}

With version 4.5.1:

O:21:"Ramsey\Uuid\Guid\Guid":1:{s:5:"bytes";s:16:"�����XK�^�^h�6$";}

enricodias avatar Nov 04 '22 00:11 enricodias

I've tried to be as backward-compatible with the object serialization and unserialization as possible. That is, I've tried to make the unserialization work in such a way that it detects the older formats and then does the right thing.

Unfortunately, the PHP upgrade path for phasing out Serializable has been a little confusing. There were these two RFCs:

  • https://wiki.php.net/rfc/custom_object_serialization
  • https://wiki.php.net/rfc/phase_out_serializable

This prompted ramsey/uuid to implement __serialize() and __unserialize() in preparation for the removal of the Serializable interface.

In the "phase out" RFC, there's this statement:

If a class implements both Serializable and __serialize()/__unserialize(), the latter take precedence (on versions that support them), and the Serializable interface is only used to decode existing serialization payload using the obsolete C format. To migrate to the new mechanism, it's possible to either replace Serializable entirely (if support for PHP 7.3 and below is not needed) or to implement both (if it is needed).

We've not fully removed the use of Serializable yet, since UuidInterface depends on it, and I don't want to cause downstream headaches resulting from interface changes. According to your bug report, it sounds like the new methods are being used to unserialize the old format, but my understanding is that they shouldn't.

Can you provide some short example code that reproduces this? Ideally, include a serialized UUID string that produces this error when you try to unserialize it.

ramsey avatar Dec 19 '22 23:12 ramsey

For us this means we have to logout every user who is logged in now. So that they won't encounter this error

I discussed with college and right now we store the whole user object in the sessions which isn't the best decisions, i think its better to store the things we want to check on https://symfony.com/doc/current/security.html#understanding-how-users-are-refreshed-from-the-session.

This was in my session: s:5:"\x00*\x00id";O:16:"Ramsey\Uuid\Uuid":1:{s:6:"string";s:36:"5b3953f9-04a5-4623-acf3-bc24e8d26c88";}} And then when i upgraded from 3.9.7 to 4.0.0 i get the following: s:5:"\x00*\x00id";C:26:"Ramsey\Uuid\Rfc4122\UuidV4":36:{5b3953f9-04a5-4623-acf3-bc24e8d26c88}} but i didn't have any errors Upgrading then to version 4.7.3 also no errors. Only if i upgrade from 3.9.7 to 4.7.3 i get the error.

johanadivare avatar Jan 26 '23 13:01 johanadivare

I can confirm updating from 3.9.7 to 4.7.4 it works without problems because it makes use of the LazyUuidFromString i tested with logging in and that stayed the same and i tested with serializing a Uuid myself. I will close this issue as it is resolved for me.

JohJohan avatar May 24 '23 10:05 JohJohan

After a day of testing on our testing environment we encountered Exceptions Ramsey\Uuid\Uuid::__unserialize(): Argument #1 ($data) is invalid again for a social logged in session. I will keep this ticket closed as we need to look at updating current session to support the new format.

JohJohan avatar May 25 '23 08:05 JohJohan