vendor/pimcore/pimcore/bundles/AdminBundle/EventListener/CsrfProtectionListener.php line 66

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Enterprise License (PEL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  * @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  * @license    http://www.pimcore.org/license     GPLv3 and PEL
  13.  */
  14. namespace Pimcore\Bundle\AdminBundle\EventListener;
  15. use Pimcore\Bundle\CoreBundle\EventListener\Traits\PimcoreContextAwareTrait;
  16. use Pimcore\Http\Request\Resolver\PimcoreContextResolver;
  17. use Pimcore\Templating\PhpEngine;
  18. use Pimcore\Tool\Session;
  19. use Psr\Log\LoggerAwareTrait;
  20. use Symfony\Component\EventDispatcher\EventSubscriberInterface;
  21. use Symfony\Component\HttpFoundation\Request;
  22. use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface;
  23. use Symfony\Component\HttpKernel\Event\GetResponseEvent;
  24. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  25. use Symfony\Component\HttpKernel\KernelEvents;
  26. class CsrfProtectionListener implements EventSubscriberInterface
  27. {
  28.     use PimcoreContextAwareTrait;
  29.     use LoggerAwareTrait;
  30.     protected $excludedRoutes = [];
  31.     protected $csrfToken null;
  32.     /**
  33.      * @var PhpEngine
  34.      */
  35.     protected $phpTemplatingEngine;
  36.     /**
  37.      * @param array $excludedRoutes
  38.      * @param PhpEngine $phpTemplatingEngine
  39.      */
  40.     public function __construct($excludedRoutesPhpEngine $phpTemplatingEngine)
  41.     {
  42.         $this->excludedRoutes $excludedRoutes;
  43.         $this->phpTemplatingEngine $phpTemplatingEngine;
  44.     }
  45.     /**
  46.      * @inheritDoc
  47.      */
  48.     public static function getSubscribedEvents()
  49.     {
  50.         return [
  51.             KernelEvents::REQUEST => ['handleRequest'11]
  52.         ];
  53.     }
  54.     /**
  55.      * @param GetResponseEvent $event
  56.      */
  57.     public function handleRequest(GetResponseEvent $event)
  58.     {
  59.         $request $event->getRequest();
  60.         if (!$this->matchesPimcoreContext($requestPimcoreContextResolver::CONTEXT_ADMIN)) {
  61.             return;
  62.         }
  63.         $this->phpTemplatingEngine->addGlobal('csrfToken'$this->getCsrfToken());
  64.         if ($request->getMethod() == Request::METHOD_GET) {
  65.             return;
  66.         }
  67.         $exludedRoutes = [
  68.             // WebDAV
  69.             'pimcore_admin_webdav',
  70.             // external applications
  71.             'pimcore_admin_external_opcache_index',
  72.             'pimcore_admin_external_linfo_index''pimcore_admin_external_linfo_layout',
  73.             'pimcore_admin_external_adminer_adminer''pimcore_admin_external_adminer_proxy',
  74.             'pimcore_admin_external_adminer_proxy_1''pimcore_admin_external_adminer_proxy_2',
  75.         ];
  76.         $route $request->attributes->get('_route');
  77.         if (in_array($route$exludedRoutes) || in_array($route$this->excludedRoutes)) {
  78.             return;
  79.         }
  80.         $this->checkCsrfToken($request);
  81.     }
  82.     /**
  83.      * @param Request $request
  84.      */
  85.     public function checkCsrfToken(Request $request)
  86.     {
  87.         $csrfToken $this->getCsrfToken();
  88.         $requestCsrfToken $request->headers->get('x_pimcore_csrf_token');
  89.         if (!$requestCsrfToken) {
  90.             $requestCsrfToken $request->get('csrfToken');
  91.         }
  92.         if (!$csrfToken || $csrfToken !== $requestCsrfToken) {
  93.             $this->logger->error('Detected CSRF attack on {request}', [
  94.                 'request' => $request->getPathInfo()
  95.             ]);
  96.             throw new AccessDeniedHttpException('Detected CSRF Attack! Do not do evil things with pimcore ... ;-)');
  97.         }
  98.     }
  99.     /**
  100.      * @return string
  101.      */
  102.     public function getCsrfToken()
  103.     {
  104.         if (!$this->csrfToken) {
  105.             $this->csrfToken Session::getReadOnly()->get('csrfToken');
  106.             if (!$this->csrfToken) {
  107.                 $this->csrfToken Session::useSession(function (AttributeBagInterface $adminSession) {
  108.                     if (!$adminSession->has('csrfToken') && !$adminSession->get('csrfToken')) {
  109.                         $adminSession->set('csrfToken'sha1(generateRandomSymfonySecret()));
  110.                     }
  111.                     return $adminSession->get('csrfToken');
  112.                 });
  113.             }
  114.         }
  115.         return $this->csrfToken;
  116.     }
  117.     public function regenerateCsrfToken()
  118.     {
  119.         $this->csrfToken Session::useSession(function (AttributeBagInterface $adminSession) {
  120.             $token sha1(generateRandomSymfonySecret());
  121.             $adminSession->set('csrfToken'$token);
  122.             return $token;
  123.         });
  124.         $this->phpTemplatingEngine->addGlobal('csrfToken'$this->csrfToken);
  125.     }
  126. }