Skip to content

Commit

Permalink
Merge pull request #47 from rawilk/unserialize-whitelist
Browse files Browse the repository at this point in the history
Add safelist for object unserialization
  • Loading branch information
rawilk authored Nov 14, 2023
2 parents c5d0663 + 8a63299 commit 7edd698
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 1 deletion.
19 changes: 19 additions & 0 deletions config/settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,4 +175,23 @@
|
*/
'cache_default_value' => true,

/*
|--------------------------------------------------------------------------
| Unserialize Safelist
|--------------------------------------------------------------------------
|
| When using the default value serializer class from this package, we
| will only unserialize objects that have their classes whitelisted here.
| Any other objects will be unserialized to something like:
| __PHP_Incomplete_Class(App\Models\User) {...}
|
| To prevent any objects from being unserialized, simply set this to
| an empty array.
*/
'unserialize_safelist' => [
\Carbon\Carbon::class,
\Carbon\CarbonImmutable::class,
\Illuminate\Support\Carbon::class,
],
];
5 changes: 4 additions & 1 deletion src/Support/ValueSerializers/ValueSerializer.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Rawilk\Settings\Support\ValueSerializers;

use Illuminate\Support\Arr;
use Rawilk\Settings\Contracts\ValueSerializer as ValueSerializerContract;

class ValueSerializer implements ValueSerializerContract
Expand All @@ -15,6 +16,8 @@ public function serialize($value): string

public function unserialize(string $serialized): mixed
{
return unserialize($serialized, ['allowed_classes' => false]);
$safelistedClasses = Arr::wrap(config('settings.unserialize_safelist', []));

return unserialize($serialized, ['allowed_classes' => $safelistedClasses]);
}
}
34 changes: 34 additions & 0 deletions tests/Unit/ValueSerializers/ValueSerializerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

declare(strict_types=1);

use Carbon\Carbon;
use Illuminate\Support\Facades\Date;
use Rawilk\Settings\Support\ValueSerializers\ValueSerializer;

it('serializes values', function (mixed $value) {
Expand All @@ -22,6 +24,38 @@
}
})->with('values');

test('certain objects can be safelisted for unserialization', function () {
config(['settings.unserialize_safelist' => [
Carbon::class,
]]);

$serializer = new ValueSerializer;

Date::setTestNow('2023-01-01 10:00:00');

$now = Carbon::now();

$serialized = serialize($now);
$unserialized = $serializer->unserialize($serialized);

expect($unserialized)->toBeInstanceOf(Carbon::class)
->and($unserialized->eq($now))->toBeTrue()
->and($unserialized->toDateTimeString())->toBe('2023-01-01 10:00:00');
});

test('objects not in the safelist will be unserialized to __PHP_Incomplete_Class', function () {
config(['settings.unserialize_safelist' => []]);

$serializer = new ValueSerializer;

$serialized = serialize(Carbon::now());
$unserialized = $serializer->unserialize($serialized);

expect($unserialized)->toBeObject()
->and($unserialized)->not->toBeInstanceOf(Carbon::class)
->and($unserialized)->toBeInstanceOf(__PHP_Incomplete_Class::class);
});

dataset('values', [
null,
1,
Expand Down

0 comments on commit 7edd698

Please sign in to comment.