Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/Twig/Extension/UtilsExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
use function Cake\Core\deprecationWarning;

/**
* Class UtilsExtension.
Expand All @@ -34,8 +35,16 @@ class UtilsExtension extends AbstractExtension
public function getFilters(): array
{
return [
new TwigFilter('serialize', 'serialize'),
new TwigFilter('unserialize', 'unserialize'),
new TwigFilter('serialize', function (string $value): mixed {
deprecationWarning('5.0.2', 'Usage of serialize in templates deprecated.');

return serialize($value);
}),
new TwigFilter('unserialize', function (string $value): mixed {
deprecationWarning('5.0.2', 'unserialize is deprecated. Its usage creates arbitrary object deserialization issues');

return unserialize($value, ['allowed_classes' => false]);
}),
new TwigFilter('md5', 'md5'),
new TwigFilter('base64_encode', 'base64_encode'),
new TwigFilter('base64_decode', 'base64_decode'),
Expand Down
55 changes: 55 additions & 0 deletions tests/TestCase/Twig/Extension/UtilsExtensionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php
declare(strict_types=1);

/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* Copyright (c) 2014 Cees-Jan Kiewiet
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @since 1.0.0
* @license https://opensource.org/licenses/mit-license.php MIT License
*/

namespace Cake\TwigView\Test\TestCase\Twig\Extension;

use Cake\TwigView\Twig\Extension\UtilsExtension;
use TestApp\GadgetMarker;
use Twig\Environment;
use Twig\Loader\ArrayLoader;

class UtilsExtensionTest extends AbstractExtensionTest
{
protected function setUp(): void
{
parent::setUp();
$this->extension = new UtilsExtension();
}

public function testUnserializePreventObject(): void
{
$this->skipIf(PHP_VERSION_ID < 80300, 'Requires PHP8.3 or higher');

$twig = new Environment(new ArrayLoader([
// {% set %} so we exercise the filter without stringifying the result.
'object' => '{% set _ = payload|unserialize %}(rendered)',
'array' => '{{ (payload|unserialize)["role"] }}',
]));
$twig->addExtension(new UtilsExtension());

// 1) Object payload: does a gadget's magic method run?
GadgetMarker::$woken = false;
$this->deprecated(function () use ($twig): void {
$twig->render('object', ['payload' => serialize(new GadgetMarker())]);
$this->assertFalse(GadgetMarker::$woken, 'Should not have modified GadgetMarker');

$out = $twig->render('array', ['payload' => serialize(['role' => 'editor'])]);
$this->assertStringContainsString('editor', $out);
});
}
}
15 changes: 15 additions & 0 deletions tests/test_app/src/GadgetMarker.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?php
declare(strict_types=1);

namespace TestApp;

class GadgetMarker
{
public static bool $woken = false;

public function __wakeup(): void
{
self::$woken = true;
echo " [!] GadgetMarker::__wakeup fired during unserialize (object injection)\n";
}
}
Loading