@@ -154,6 +154,11 @@ class Security implements SecurityInterface
154154 */
155155 private ?Session $ session = null ;
156156
157+ /**
158+ * CSRF Hash in Cookie
159+ */
160+ private ?string $ hashInCookie = null ;
161+
157162 /**
158163 * Constructor.
159164 *
@@ -192,7 +197,8 @@ public function __construct(App $config)
192197 $ this ->configureSession ();
193198 }
194199
195- $ this ->request = Services::request ();
200+ $ this ->request = Services::request ();
201+ $ this ->hashInCookie = $ this ->request ->getCookie ($ this ->cookieName );
196202
197203 $ this ->generateHash ();
198204 }
@@ -308,7 +314,7 @@ public function verify(RequestInterface $request)
308314 if ($ this ->regenerate ) {
309315 $ this ->hash = null ;
310316 if ($ this ->isCSRFCookie ()) {
311- unset( $ _COOKIE [ $ this ->cookieName ]) ;
317+ $ this ->hashInCookie = null ;
312318 } else {
313319 // Session based CSRF protection
314320 $ this ->session ->remove ($ this ->tokenName );
@@ -504,7 +510,7 @@ protected function generateHash(): string
504510 // sub-pages causing this feature to fail
505511 if ($ this ->isCSRFCookie ()) {
506512 if ($ this ->isHashInCookie ()) {
507- return $ this ->hash = $ _COOKIE [ $ this ->cookieName ] ;
513+ return $ this ->hash = $ this ->hashInCookie ;
508514 }
509515 } elseif ($ this ->session ->has ($ this ->tokenName )) {
510516 // Session based CSRF protection
@@ -526,9 +532,14 @@ protected function generateHash(): string
526532
527533 private function isHashInCookie (): bool
528534 {
529- return isset ($ _COOKIE [$ this ->cookieName ])
530- && is_string ($ _COOKIE [$ this ->cookieName ])
531- && preg_match ('#^[0-9a-f]{32}$#iS ' , $ _COOKIE [$ this ->cookieName ]) === 1 ;
535+ if ($ this ->hashInCookie === null ) {
536+ return false ;
537+ }
538+
539+ $ length = static ::CSRF_HASH_BYTES * 2 ;
540+ $ pattern = '#^[0-9a-f]{ ' . $ length . '}$#iS ' ;
541+
542+ return preg_match ($ pattern , $ this ->hashInCookie ) === 1 ;
532543 }
533544
534545 private function saveHashInCookie (): void
0 commit comments