Skip to content

Commit

Permalink
[LiveComponent] Check secret is not empty + add missing [SensitivePar…
Browse files Browse the repository at this point in the history
…ameter]

Improve security before we allow secret customization for LiveComponents (cf symfony#2453)

I consider this a fix as passing an empty string for secret produce the same hash as passing null... which is deprecated for obvious reasons.
  • Loading branch information
smnandre committed Dec 21, 2024
1 parent c3ee75b commit 3c3d097
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 3 deletions.
5 changes: 4 additions & 1 deletion src/LiveComponent/src/LiveComponentHydrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,11 @@ public function __construct(
private PropertyAccessorInterface $propertyAccessor,
private LiveComponentMetadataFactory $liveComponentMetadataFactory,
private NormalizerInterface|DenormalizerInterface|null $serializer,
private string $secret,
#[\SensitiveParameter] private string $secret,
) {
if (!$secret) {
throw new \InvalidArgumentException('A non-empty secret is required.');
}
}

public function dehydrate(object $component, ComponentAttributes $attributes, LiveComponentMetadata $componentMetadata): DehydratedProps
Expand Down
7 changes: 5 additions & 2 deletions src/LiveComponent/src/Util/FingerprintCalculator.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,14 @@
*
* @internal
*/
class FingerprintCalculator
final class FingerprintCalculator
{
public function __construct(
private string $secret,
#[\SensitiveParameter] private string $secret,
) {
if (!$secret) {
throw new \InvalidArgumentException('A non-empty secret is required.');
}
}

public function calculateFingerprint(array $inputProps, LiveComponentMetadata $liveMetadata): string
Expand Down
35 changes: 35 additions & 0 deletions src/LiveComponent/tests/Unit/LiveComponentHydratorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\UX\LiveComponent\Tests\Unit;

use PHPUnit\Framework\TestCase;
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\UX\LiveComponent\LiveComponentHydrator;
use Symfony\UX\LiveComponent\Metadata\LiveComponentMetadataFactory;

final class LiveComponentHydratorTest extends TestCase
{
public function testConstructWithEmptySecret(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('A non-empty secret is required.');

new LiveComponentHydrator(
[],
$this->createMock(PropertyAccessorInterface::class),
$this->createMock(LiveComponentMetadataFactory::class),
$this->createMock(NormalizerInterface::class),
'',
);
}
}
26 changes: 26 additions & 0 deletions src/LiveComponent/tests/Unit/Util/FingerprintCalculatorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\UX\LiveComponent\Tests\Unit\Util;

use PHPUnit\Framework\TestCase;
use Symfony\UX\LiveComponent\Util\FingerprintCalculator;

final class FingerprintCalculatorTest extends TestCase
{
public function testConstructWithEmptySecret(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionMessage('A non-empty secret is required.');

new FingerprintCalculator('');
}
}

0 comments on commit 3c3d097

Please sign in to comment.