diff --git a/typo3/sysext/core/Classes/Authentication/AbstractUserAuthentication.php b/typo3/sysext/core/Classes/Authentication/AbstractUserAuthentication.php
index ecc4e515f2a91b6e7aa54e2bef11d7b22746c9a4..f6ec44d29b5c90ae33b8e4150136cd8095d737b6 100644
--- a/typo3/sysext/core/Classes/Authentication/AbstractUserAuthentication.php
+++ b/typo3/sysext/core/Classes/Authentication/AbstractUserAuthentication.php
@@ -29,6 +29,7 @@ use TYPO3\CMS\Core\Database\Query\Restriction\QueryRestrictionContainerInterface
 use TYPO3\CMS\Core\Database\Query\Restriction\RootLevelRestriction;
 use TYPO3\CMS\Core\Database\Query\Restriction\StartTimeRestriction;
 use TYPO3\CMS\Core\Exception;
+use TYPO3\CMS\Core\Http\CookieHeaderTrait;
 use TYPO3\CMS\Core\Session\Backend\Exception\SessionNotFoundException;
 use TYPO3\CMS\Core\Session\Backend\SessionBackendInterface;
 use TYPO3\CMS\Core\Session\SessionManager;
@@ -49,6 +50,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
 abstract class AbstractUserAuthentication implements LoggerAwareInterface
 {
     use LoggerAwareTrait;
+    use CookieHeaderTrait;
 
     /**
      * Session/Cookie name
@@ -452,8 +454,11 @@ abstract class AbstractUserAuthentication implements LoggerAwareInterface
             $cookieExpire = $isRefreshTimeBasedCookie ? $GLOBALS['EXEC_TIME'] + $this->lifetime : 0;
             // Use the secure option when the current request is served by a secure connection:
             $cookieSecure = (bool)$settings['cookieSecure'] && GeneralUtility::getIndpEnv('TYPO3_SSL');
-            $cookieSameSite = $this->getCookieSameSite();
-            // None needs the secure option (only allowed on HTTPS)
+            // Valid options are "strict", "lax" or "none", whereas "none" only works in HTTPS requests (default & fallback is "strict")
+            $cookieSameSite = $this->sanitizeSameSiteCookieValue(
+                strtolower($GLOBALS['TYPO3_CONF_VARS'][$this->loginType]['cookieSameSite'] ?? Cookie::SAMESITE_STRICT)
+            );
+            // SameSite "none" needs the secure option (only allowed on HTTPS)
             if ($cookieSameSite === Cookie::SAMESITE_NONE) {
                 $cookieSecure = true;
             }
@@ -482,24 +487,6 @@ abstract class AbstractUserAuthentication implements LoggerAwareInterface
         }
     }
 
-    /**
-     * Fetches the cookie information from the current LocalConfiguration option, based on the $loginType
-     * which is either "BE" or "FE".
-     * Valid options are "strict", "lax" or "none", whereas "none" only works in HTTPS requests.
-     *
-     * If nothing is defined, or a wrong value is defined, a fallback to "strict" is put in place.
-     *
-     * @return string
-     */
-    protected function getCookieSameSite(): string
-    {
-        $cookieSameSite = strtolower($GLOBALS['TYPO3_CONF_VARS'][$this->loginType]['cookieSameSite'] ?? Cookie::SAMESITE_STRICT);
-        if (!in_array($cookieSameSite, [Cookie::SAMESITE_STRICT, Cookie::SAMESITE_LAX, Cookie::SAMESITE_NONE], true)) {
-            $cookieSameSite = Cookie::SAMESITE_STRICT;
-        }
-        return $cookieSameSite;
-    }
-
     /**
      * Gets the domain to be used on setting cookies.
      * The information is taken from the value in $GLOBALS['TYPO3_CONF_VARS']['SYS']['cookieDomain'].
diff --git a/typo3/sysext/core/Classes/Http/CookieHeaderTrait.php b/typo3/sysext/core/Classes/Http/CookieHeaderTrait.php
new file mode 100644
index 0000000000000000000000000000000000000000..5432a4578d167901eb4f44b7186ec412c88d5ebb
--- /dev/null
+++ b/typo3/sysext/core/Classes/Http/CookieHeaderTrait.php
@@ -0,0 +1,74 @@
+<?php
+declare(strict_types = 1);
+namespace TYPO3\CMS\Core\Http;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use Symfony\Component\HttpFoundation\Cookie;
+
+trait CookieHeaderTrait
+{
+    private function hasSameSiteCookieSupport(): bool
+    {
+        return version_compare(PHP_VERSION, '7.3.0', '>=');
+    }
+
+    /**
+     * Since PHP < 7.3 is not capable of sending the same-site cookie information, session_start() effectively
+     * sends the Set-Cookie header. This method fetches the set-cookie headers, parses it via Symfony's Cookie
+     * object, and resends the header.
+     *
+     * @param string[] $cookieNames
+     */
+    private function resendCookieHeader(array $cookieNames = []): void
+    {
+        $cookies = array_filter(headers_list(), function (string $header) {
+            return stripos($header, 'Set-Cookie:') === 0;
+        });
+        $cookies = array_map(function (string $cookieHeader) use ($cookieNames) {
+            $payload = ltrim(substr($cookieHeader, 11));
+            $cookie = Cookie::fromString($payload);
+            $sameSite = $cookie->getSameSite();
+            // adjust SameSite flag only for given cookie names (applied to all if not declared)
+            if (empty($cookieNames) || in_array($cookie->getName(), $cookieNames, true)) {
+                $sameSite = $sameSite ?? Cookie::SAMESITE_STRICT;
+            }
+            return (string)Cookie::create(
+                $cookie->getName(),
+                $cookie->getValue(),
+                $cookie->getExpiresTime(),
+                $cookie->getPath(),
+                $cookie->getDomain(),
+                $cookie->isSecure(),
+                $cookie->isHttpOnly(),
+                $cookie->isRaw(),
+                $sameSite
+            );
+        }, $cookies);
+        if (!empty($cookies)) {
+            header_remove('Set-Cookie');
+            foreach ($cookies as $cookie) {
+                header('Set-Cookie: ' . $cookie, false);
+            }
+        }
+    }
+
+    private function sanitizeSameSiteCookieValue(string $cookieSameSite): string
+    {
+        if (!in_array($cookieSameSite, [Cookie::SAMESITE_STRICT, Cookie::SAMESITE_LAX, Cookie::SAMESITE_NONE], true)) {
+            $cookieSameSite = Cookie::SAMESITE_STRICT;
+        }
+        return $cookieSameSite;
+    }
+}
diff --git a/typo3/sysext/install/Classes/Service/SessionService.php b/typo3/sysext/install/Classes/Service/SessionService.php
index 92593cc85eae9e8390ade46f9ea8fc262cf787f0..86069a1e8f3772a3c4d9e3894ca1066b79a1bbc2 100644
--- a/typo3/sysext/install/Classes/Service/SessionService.php
+++ b/typo3/sysext/install/Classes/Service/SessionService.php
@@ -16,6 +16,7 @@ namespace TYPO3\CMS\Install\Service;
 
 use Symfony\Component\HttpFoundation\Cookie;
 use TYPO3\CMS\Core\Core\Environment;
+use TYPO3\CMS\Core\Http\CookieHeaderTrait;
 use TYPO3\CMS\Core\Messaging\FlashMessage;
 use TYPO3\CMS\Core\SingletonInterface;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -26,6 +27,8 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
  */
 class SessionService implements SingletonInterface
 {
+    use CookieHeaderTrait;
+
     /**
      * The path to our var/ folder (where we can write our sessions). Set in the
      * constructor.
@@ -78,7 +81,7 @@ class SessionService implements SingletonInterface
         session_save_path($sessionSavePath);
         session_name($this->cookieName);
         ini_set('session.cookie_httponly', true);
-        if (PHP_VERSION_ID >= 70300) {
+        if ($this->hasSameSiteCookieSupport()) {
             ini_set('session.cookie_samesite', Cookie::SAMESITE_STRICT);
         }
         ini_set('session.cookie_path', (string)GeneralUtility::getIndpEnv('TYPO3_SITE_PATH'));
@@ -98,44 +101,11 @@ class SessionService implements SingletonInterface
             throw new \TYPO3\CMS\Install\Exception($sessionCreationError, 1294587486);
         }
         session_start();
-        if (PHP_VERSION_ID < 70300) {
+        if (!$this->hasSameSiteCookieSupport()) {
             $this->resendCookieHeader();
         }
     }
 
-    /**
-     * Since PHP < 7.3 is not capable of sending the same-site cookie information, session_start() effectively
-     * sends the Set-Cookie header. This method fetches the set-cookie headers, parses it via Symfony's Cookie
-     * object, and resends the header.
-     */
-    private function resendCookieHeader()
-    {
-        $cookies = array_filter(headers_list(), function (string $header) {
-            return stripos($header, 'Set-Cookie:') === 0;
-        });
-        $cookies = array_map(function (string $cookieHeader) {
-            $payload = ltrim(substr($cookieHeader, 11));
-            $cookie = Cookie::fromString($payload);
-            return (string)Cookie::create(
-                $cookie->getName(),
-                $cookie->getValue(),
-                $cookie->getExpiresTime(),
-                $cookie->getPath(),
-                $cookie->getDomain(),
-                $cookie->isSecure(),
-                $cookie->isHttpOnly(),
-                $cookie->isRaw(),
-                $cookie->getSameSite() ?? Cookie::SAMESITE_STRICT
-            );
-        }, $cookies);
-        if (!empty($cookies)) {
-            header_remove('Set-Cookie');
-            foreach ($cookies as $cookie) {
-                header('Set-Cookie: ' . $cookie, false);
-            }
-        }
-    }
-
     /**
      * Returns the path where to store our session files
      *
@@ -234,6 +204,9 @@ class SessionService implements SingletonInterface
     private function renewSession()
     {
         session_regenerate_id();
+        if (!$this->hasSameSiteCookieSupport()) {
+            $this->resendCookieHeader([$this->cookieName]);
+        }
         return session_id();
     }
 
diff --git a/typo3/sysext/workspaces/Classes/Middleware/WorkspacePreview.php b/typo3/sysext/workspaces/Classes/Middleware/WorkspacePreview.php
index 3d450b119c06031eb67aa16481389fa455674a5b..84c308af5f25c5925aca81bfb60c2d1cc3b7b93a 100644
--- a/typo3/sysext/workspaces/Classes/Middleware/WorkspacePreview.php
+++ b/typo3/sysext/workspaces/Classes/Middleware/WorkspacePreview.php
@@ -19,11 +19,13 @@ use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\ServerRequestInterface;
 use Psr\Http\Server\MiddlewareInterface;
 use Psr\Http\Server\RequestHandlerInterface;
+use Symfony\Component\HttpFoundation\Cookie;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
 use TYPO3\CMS\Core\Context\Context;
 use TYPO3\CMS\Core\Context\UserAspect;
 use TYPO3\CMS\Core\Context\WorkspaceAspect;
 use TYPO3\CMS\Core\Database\ConnectionPool;
+use TYPO3\CMS\Core\Http\CookieHeaderTrait;
 use TYPO3\CMS\Core\Http\HtmlResponse;
 use TYPO3\CMS\Core\Http\NormalizedParams;
 use TYPO3\CMS\Core\Http\Stream;
@@ -43,6 +45,8 @@ use TYPO3\CMS\Workspaces\Authentication\PreviewUserAuthentication;
  */
 class WorkspacePreview implements MiddlewareInterface
 {
+    use CookieHeaderTrait;
+
     /**
      * The GET parameter to be used (also the cookie name)
      *
@@ -221,7 +225,24 @@ class WorkspacePreview implements MiddlewareInterface
      */
     protected function setCookie(string $inputCode, NormalizedParams $normalizedParams)
     {
-        setcookie($this->previewKey, $inputCode, 0, $normalizedParams->getSitePath(), '', true, true);
+        $cookieSameSite = $this->sanitizeSameSiteCookieValue(
+            strtolower($GLOBALS['TYPO3_CONF_VARS']['BE']['cookieSameSite'] ?? Cookie::SAMESITE_STRICT)
+        );
+        // None needs the secure option (only allowed on HTTPS)
+        $cookieSecure = $cookieSameSite === Cookie::SAMESITE_NONE || $normalizedParams->isHttps();
+
+        $cookie = new Cookie(
+            $this->previewKey,
+            $inputCode,
+            0,
+            $normalizedParams->getSitePath(),
+            null,
+            $cookieSecure,
+            true,
+            false,
+            $cookieSameSite
+        );
+        header('Set-Cookie: ' . $cookie->__toString(), false);
     }
 
     /**