Restrict allowed classes in Profile::unserialize()

This commit is contained in:
Fabien Potencier
2026-05-23 09:00:10 +02:00
parent c6bbae295b
commit 4c1dae5e71
3 changed files with 29 additions and 1 deletions
+1
View File
@@ -1,5 +1,6 @@
# 3.27.0 (2026-XX-XX)
* Restrict allowed classes in `Twig\Profiler\Profile::unserialize()` to prevent arbitrary class instantiation
* Deprecate the `Twig\Sandbox\SourcePolicyInterface` interface with no replacement
# 3.26.0 (2026-05-20)
+1 -1
View File
@@ -173,7 +173,7 @@ final class Profile implements \IteratorAggregate, \Serializable
public function unserialize($data): void
{
$this->__unserialize(unserialize($data));
$this->__unserialize(unserialize($data, ['allowed_classes' => [self::class]]));
}
/**
+27
View File
@@ -121,6 +121,23 @@ class ProfileTest extends TestCase
$this->assertEquals($profile1->getName(), $profile3->getName());
}
public function testUnserializeDoesNotInstantiateArbitraryClasses()
{
$payload = serialize([
'template',
'name',
Profile::ROOT,
[],
[],
[new ProfileTestProbe()],
]);
$profile = new Profile();
$profile->unserialize($payload);
$this->assertFalse(ProfileTestProbe::$wakeupCalled, 'Magic unserialize methods must not be called on arbitrary classes');
}
public function testReset()
{
$profile = new Profile();
@@ -131,3 +148,13 @@ class ProfileTest extends TestCase
$this->assertEquals(0, $profile->getDuration());
}
}
class ProfileTestProbe
{
public static bool $wakeupCalled = false;
public function __unserialize(array $data): void
{
self::$wakeupCalled = true;
}
}