$keepOnly) { $_SESSION['csrf_pool'] = array_slice($_SESSION['csrf_pool'], -$keepOnly, null, true); } } /** * Get CSRF Token for use with HTML Form * @return string Hidden Form with token set */ public static function csrfTokenTag(): string { $token = self::createCsrfToken(); return ""; } public static function csrfTokenStillValid(string $csrfTokenKeyName = ""): bool { if (empty($csrfTokenKeyName)) { $csrfTokenKeyName = $_POST['csrf_token'] ?? ""; } $validTimeStamp = self::csrfTokenIsValid($csrfTokenKeyName); if ($validTimeStamp === false) { return false; } $recent = self::csrfTokenIsRecent($validTimeStamp); self::destroyCsrfToken($csrfTokenKeyName); // Done, so clean up Consume token return $recent; } /** * Get an Cross-Site Request Forge - Prevention Token * @return string */ private static function csrfToken(): string { return self::getUniqueId(); } private static function setup(): void { $clean_ts = intval(Configure::get( 'security', 'token_life' )); if ($clean_ts < 60) { $clean_ts = 3600; } if (!isset($_SESSION['csrf_pool'])) { $_SESSION['csrf_pool'] = []; } // Clean old tokens by useage time token_life foreach ($_SESSION['csrf_pool'] as $key => $timestamp) { if ($timestamp < (time() - $clean_ts)) { unset($_SESSION['csrf_pool'][$key]); } } } private static function csrfTokenIsValid(string $csrfTokenKeyName = ""): false|int { if (empty($csrfTokenKeyName)) { $csrfTokenKeyName = $_POST['csrf_token'] ?? ""; } if (!isset($_SESSION['csrf_pool'][$csrfTokenKeyName])) { return false; } $tsToken = $_SESSION['csrf_pool'][$csrfTokenKeyName]; if (is_int($tsToken)){ return $tsToken; } return false; } private static function csrfTokenIsRecent($tokenTimeStored): bool { $max_elapsed = intval(Configure::get( 'security', 'max_token_age' )); if ($max_elapsed < 30) { $max_elapsed = 60 * 60 * 24; // 1 day } return ($tokenTimeStored + $max_elapsed) >= time(); } /** * Destroy CSRF Token from Session * @return bool success */ private static function destroyCsrfToken(string $csrfTokenKeyName = ""): bool { if (empty($csrfTokenKeyName)) { $csrfTokenKeyName = $_POST['csrf_token'] ?? ""; } if (!isset($_SESSION['csrf_pool'][$csrfTokenKeyName])) { return false; } unset($_SESSION['csrf_pool'][$csrfTokenKeyName]); // Consume token return true; } }