vendor/stimactiv/core-bundle/src/Model/ReplayPreventerManager.php line 44

Open in your IDE?
  1. <?php
  2. namespace Stimactiv\CoreBundle\Model;
  3. use Stimactiv\LogBundle\Model\SiteLogManager;
  4. use Symfony\Component\HttpFoundation\RequestStack;
  5. class ReplayPreventerManager
  6. {
  7.     private SiteLogManager $logger;
  8.     private RequestStack $requestStack;
  9.     public function __construct(RequestStack $requestStackSiteLogManager $siteLogManager)
  10.     {
  11.         $this->logger $siteLogManager;
  12.         $this->requestStack $requestStack;
  13.     }
  14.     /**
  15.      * Initialize a unique token in session to prevent replay attacks
  16.      * @param $formName string the name of the form that will be used.
  17.      * @return bool|string Either the unique key created or FALSE otherwise.
  18.      */
  19.     public function getKey(string $formName)
  20.     {
  21.         $request $this->requestStack->getCurrentRequest();
  22.         if ($request === null) {
  23.             $this->logger->reportReplayTokenErrorIntoDB(
  24.                 $formName '_getKey'__FILE__"Attempted validate a form token out of request : " $formName
  25.             );
  26.             return false;
  27.         }
  28.         $session $request->getSession();
  29.         $token $this->createUniqueKey();
  30.         $uniqueString $formName ":" $token;
  31.         $tokenStack $session->get("antiReplayToken", []);
  32.         $tokenStack[] = $uniqueString;
  33.         $session->set("antiReplayToken"$tokenStack);
  34.         return $token;
  35.     }
  36.     /**
  37.      * Validates a anti attack token stored in session.
  38.      * @param $formName string the name of the form used.
  39.      * @return bool Either the request is validate or not.
  40.      */
  41.     public function validate(string $formName)
  42.     {
  43.         $request $this->requestStack->getCurrentRequest();
  44.         if ($request === null) {
  45.             $this->logger->reportReplayTokenErrorIntoDB(
  46.                 $formName '_submit'__FILE__"Attempted validate a form token out of request : " $formName
  47.             );
  48.             return false;
  49.         }
  50.         $session $request->getSession();
  51.         $formToken $request->query->get("formToken");
  52.         if ($formToken === null) {
  53.             $this->logger->reportReplayTokenErrorIntoDB(
  54.                 $formName '_submit'__FILE__"Form token not in query parameters : " $formName
  55.             );
  56.             return false;
  57.         }
  58.         if (false === $session->has("antiReplayToken")) {
  59.             $this->logger->reportReplayTokenErrorIntoDB(
  60.                 $formName '_submit'__FILE__"Session does not have the antiReplayToken stack : " $formName
  61.             );
  62.             return false;
  63.         }
  64.         $tokenStack $session->get("antiReplayToken");
  65.         if ($tokenStack === null || false === is_array($tokenStack)) {
  66.             $this->logger->reportReplayTokenErrorIntoDB(
  67.                 $formName '_submit'__FILE__"antiReplayToken is not as expected in session : " $formName
  68.             );
  69.             $session->set("antiReplayToken", []);
  70.             return false;
  71.         }
  72.         $tokenStackAsString json_encode($tokenStack);
  73.         $uniqueString $formName ":" $formToken;
  74.         $key array_search($uniqueString$tokenStack);
  75.         if (false === $key) {
  76.             $this->logger->reportReplayTokenErrorIntoDB(
  77.                 $formName '_submit'__FILE__"Token not in antiReplayToken (tokens in session : " $tokenStackAsString ", token provided by form : " $uniqueString ")"
  78.             );
  79.             return false;
  80.         }
  81.         unset($tokenStack[$key]);
  82.         $tokenStack array_values($tokenStack);
  83.         $session->set("antiReplayToken"$tokenStack);
  84.         return true;
  85.     }
  86.     /**
  87.      * Generates a randomly generated cryptographic secure key.
  88.      * @return string the generated key.
  89.      */
  90.     private function createUniqueKey(): string
  91.     {
  92.         $valid false;
  93.         $key null;
  94.         while (false === $valid) {
  95.             $key bin2hex(openssl_random_pseudo_bytes(16$valid));
  96.         }
  97.         return $key;
  98.     }
  99. }