vendor/pimcore/pimcore/bundles/AdminBundle/Security/CsrfProtectionHandler.php line 78

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 Commercial License (PCL)
  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 PCL
  13. */
  14. namespace Pimcore\Bundle\AdminBundle\Security;
  15. use Pimcore\Tool\Session;
  16. use Psr\Log\LoggerAwareInterface;
  17. use Psr\Log\LoggerAwareTrait;
  18. use Symfony\Component\HttpFoundation\Request;
  19. use Symfony\Component\HttpFoundation\Session\Attribute\AttributeBagInterface;
  20. use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
  21. use Twig\Environment;
  22. /**
  23. * @internal
  24. */
  25. class CsrfProtectionHandler implements LoggerAwareInterface
  26. {
  27. use LoggerAwareTrait;
  28. protected $excludedRoutes = [];
  29. protected $csrfToken = null;
  30. /**
  31. * @var Environment
  32. */
  33. protected $twig;
  34. /**
  35. * @param array $excludedRoutes
  36. * @param Environment $twig
  37. */
  38. public function __construct($excludedRoutes, Environment $twig)
  39. {
  40. $this->excludedRoutes = $excludedRoutes;
  41. $this->twig = $twig;
  42. }
  43. /**
  44. * @param Request $request
  45. */
  46. public function checkCsrfToken(Request $request)
  47. {
  48. $csrfToken = $this->getCsrfToken();
  49. $requestCsrfToken = $request->headers->get('x_pimcore_csrf_token');
  50. if (!$requestCsrfToken) {
  51. $requestCsrfToken = $request->get('csrfToken');
  52. }
  53. if (!$csrfToken || $csrfToken !== $requestCsrfToken) {
  54. $this->logger->error('Detected CSRF attack on {request}', [
  55. 'request' => $request->getPathInfo(),
  56. ]);
  57. throw new AccessDeniedHttpException('Detected CSRF Attack! Do not do evil things with pimcore ... ;-)');
  58. }
  59. }
  60. /**
  61. * @return string
  62. */
  63. public function getCsrfToken()
  64. {
  65. if (!$this->csrfToken) {
  66. $this->csrfToken = Session::getReadOnly()->get('csrfToken');
  67. if (!$this->csrfToken) {
  68. $this->regenerateCsrfToken(false);
  69. }
  70. }
  71. return $this->csrfToken;
  72. }
  73. public function regenerateCsrfToken(bool $force = true)
  74. {
  75. $this->csrfToken = Session::useSession(function (AttributeBagInterface $adminSession) use ($force) {
  76. if ($force || !$adminSession->get('csrfToken')) {
  77. $adminSession->set('csrfToken', sha1(generateRandomSymfonySecret()));
  78. }
  79. return $adminSession->get('csrfToken');
  80. });
  81. $this->twig->addGlobal('csrfToken', $this->csrfToken);
  82. }
  83. public function generateCsrfToken()
  84. {
  85. $this->twig->addGlobal('csrfToken', $this->getCsrfToken());
  86. }
  87. /**
  88. * @return array
  89. */
  90. public function getExcludedRoutes(): array
  91. {
  92. return $this->excludedRoutes;
  93. }
  94. }