Secure the twig renderer template loader

This commit is contained in:
Tim 2025-05-11 00:37:50 +02:00
parent 6adc8c4a69
commit e3549f722a
2 changed files with 12 additions and 1 deletions

View File

@ -4,7 +4,9 @@ namespace App\Service\SnipParser\Twig;
use App\Entity\Snip; use App\Entity\Snip;
use App\Repository\SnipRepository; use App\Repository\SnipRepository;
use App\Security\Voter\SnipVoter;
use App\Service\SnipContent\SnipContentService; use App\Service\SnipContent\SnipContentService;
use Symfony\Bundle\SecurityBundle\Security;
use Twig\Error\LoaderError; use Twig\Error\LoaderError;
use Twig\Loader\LoaderInterface; use Twig\Loader\LoaderInterface;
use Twig\Source; use Twig\Source;
@ -14,6 +16,7 @@ class SnipLoader implements LoaderInterface
public function __construct( public function __construct(
private readonly SnipRepository $repository, private readonly SnipRepository $repository,
private readonly SnipContentService $contentService, private readonly SnipContentService $contentService,
private readonly Security $security,
) {} ) {}
public function getSourceContext(string $name): Source public function getSourceContext(string $name): Source
@ -50,6 +53,9 @@ class SnipLoader implements LoaderInterface
if (!$snip) { if (!$snip) {
throw new LoaderError(\sprintf('Template "%s" is not defined.', $key)); throw new LoaderError(\sprintf('Template "%s" is not defined.', $key));
} }
if (!$this->security->isGranted(SnipVoter::VIEW, $snip)) {
throw new LoaderError(\sprintf('You do not have permission to view the template "%s".', $key));
}
return $snip; return $snip;
} }

View File

@ -48,8 +48,13 @@ class SnipTwigExtension extends AbstractExtension
private function snipsByTag(string $tag): array private function snipsByTag(string $tag): array
{ {
// Todo: get 'context' user from the snip it is called from
$user = $this->security->getUser();
if ($user === null) {
return [];
}
$request = new SnipFilterRequest(SnipFilterRequest::VISIBILITY_ALL, tag: $tag); $request = new SnipFilterRequest(SnipFilterRequest::VISIBILITY_ALL, tag: $tag);
$snips = $this->snipRepo->findByRequest($this->security->getUser(), $request); $snips = $this->snipRepo->findByRequest($user, $request);
return array_map(fn(Snip $snip) => [ return array_map(fn(Snip $snip) => [
'id' => $snip->getId(), 'id' => $snip->getId(),
'name' => $snip->getName(), 'name' => $snip->getName(),