From ab4fec2a1aea46488e3dc2b9cca0712f3fa202b0 Mon Sep 17 00:00:00 2001
From: Oliver Hader <oliver@typo3.org>
Date: Tue, 12 May 2020 11:22:04 +0200
Subject: [PATCH] [SECURITY] Prevent destructors with side-effects from being
 unserialized

Deserialization of objects could lead to arbitrary removal of resources
as well as sending out message via mail.

Resolves: #88573
Resolves: #90316
Releases: master, 9.5
Change-Id: I3f77928203f4929bc715f548fb9bfdc0cd749e93
Security-Bulletin: TYPO3-CORE-SA-2020-004
Security-References: CVE-2020-11066
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/64468
Tested-by: Oliver Hader <oliver.hader@typo3.org>
Reviewed-by: Oliver Hader <oliver.hader@typo3.org>
---
 .../FormProtection/AbstractFormProtection.php |  3 ++
 .../core/Classes/Locking/FileLockStrategy.php |  4 +-
 .../Classes/Locking/SemaphoreLockStrategy.php |  4 +-
 .../Classes/Locking/SimpleLockStrategy.php    |  4 +-
 .../Classes/Log/Writer/AbstractWriter.php     |  3 ++
 .../sysext/core/Classes/Mail/MemorySpool.php  |  2 +
 .../Security/BlockSerializationTrait.php      | 40 +++++++++++++++++++
 .../core/Classes/Service/AbstractService.php  |  2 +
 .../Classes/Reflection/ReflectionService.php  |  3 ++
 .../UploadExtensionFileController.php         |  3 ++
 .../Service/Session/FileSessionHandler.php    |  3 ++
 .../Classes/Service/SessionService.php        |  2 +
 12 files changed, 70 insertions(+), 3 deletions(-)
 create mode 100644 typo3/sysext/core/Classes/Security/BlockSerializationTrait.php

diff --git a/typo3/sysext/core/Classes/FormProtection/AbstractFormProtection.php b/typo3/sysext/core/Classes/FormProtection/AbstractFormProtection.php
index 5e7d06cb29d9..4226c9c58526 100644
--- a/typo3/sysext/core/Classes/FormProtection/AbstractFormProtection.php
+++ b/typo3/sysext/core/Classes/FormProtection/AbstractFormProtection.php
@@ -16,6 +16,7 @@
 namespace TYPO3\CMS\Core\FormProtection;
 
 use TYPO3\CMS\Core\Crypto\Random;
+use TYPO3\CMS\Core\Security\BlockSerializationTrait;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
@@ -27,6 +28,8 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
  */
 abstract class AbstractFormProtection
 {
+    use BlockSerializationTrait;
+
     /**
      * @var \Closure
      */
diff --git a/typo3/sysext/core/Classes/Locking/FileLockStrategy.php b/typo3/sysext/core/Classes/Locking/FileLockStrategy.php
index dffa514e08b6..5ce26c230bb7 100644
--- a/typo3/sysext/core/Classes/Locking/FileLockStrategy.php
+++ b/typo3/sysext/core/Classes/Locking/FileLockStrategy.php
@@ -19,6 +19,7 @@ use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Locking\Exception\LockAcquireException;
 use TYPO3\CMS\Core\Locking\Exception\LockAcquireWouldBlockException;
 use TYPO3\CMS\Core\Locking\Exception\LockCreateException;
+use TYPO3\CMS\Core\Security\BlockSerializationTrait;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
@@ -26,8 +27,9 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
  */
 class FileLockStrategy implements LockingStrategyInterface
 {
-    const FILE_LOCK_FOLDER = 'lock/';
+    use BlockSerializationTrait;
 
+    const FILE_LOCK_FOLDER = 'lock/';
     const DEFAULT_PRIORITY = 75;
 
     /**
diff --git a/typo3/sysext/core/Classes/Locking/SemaphoreLockStrategy.php b/typo3/sysext/core/Classes/Locking/SemaphoreLockStrategy.php
index e0af62d44cee..ae5c42b378ab 100644
--- a/typo3/sysext/core/Classes/Locking/SemaphoreLockStrategy.php
+++ b/typo3/sysext/core/Classes/Locking/SemaphoreLockStrategy.php
@@ -18,6 +18,7 @@ namespace TYPO3\CMS\Core\Locking;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Locking\Exception\LockAcquireException;
 use TYPO3\CMS\Core\Locking\Exception\LockCreateException;
+use TYPO3\CMS\Core\Security\BlockSerializationTrait;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
@@ -25,8 +26,9 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
  */
 class SemaphoreLockStrategy implements LockingStrategyInterface
 {
-    const FILE_LOCK_FOLDER = 'lock/';
+    use BlockSerializationTrait;
 
+    const FILE_LOCK_FOLDER = 'lock/';
     const DEFAULT_PRIORITY = 25;
 
     /**
diff --git a/typo3/sysext/core/Classes/Locking/SimpleLockStrategy.php b/typo3/sysext/core/Classes/Locking/SimpleLockStrategy.php
index 892b2f361a02..374a60722553 100644
--- a/typo3/sysext/core/Classes/Locking/SimpleLockStrategy.php
+++ b/typo3/sysext/core/Classes/Locking/SimpleLockStrategy.php
@@ -18,6 +18,7 @@ namespace TYPO3\CMS\Core\Locking;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Locking\Exception\LockAcquireWouldBlockException;
 use TYPO3\CMS\Core\Locking\Exception\LockCreateException;
+use TYPO3\CMS\Core\Security\BlockSerializationTrait;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
 /**
@@ -25,8 +26,9 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
  */
 class SimpleLockStrategy implements LockingStrategyInterface
 {
-    const FILE_LOCK_FOLDER = 'lock/';
+    use BlockSerializationTrait;
 
+    const FILE_LOCK_FOLDER = 'lock/';
     const DEFAULT_PRIORITY = 50;
 
     /**
diff --git a/typo3/sysext/core/Classes/Log/Writer/AbstractWriter.php b/typo3/sysext/core/Classes/Log/Writer/AbstractWriter.php
index 9a93a56ff30d..c8c38c137286 100644
--- a/typo3/sysext/core/Classes/Log/Writer/AbstractWriter.php
+++ b/typo3/sysext/core/Classes/Log/Writer/AbstractWriter.php
@@ -16,12 +16,15 @@
 namespace TYPO3\CMS\Core\Log\Writer;
 
 use TYPO3\CMS\Core\Log\Exception\InvalidLogWriterConfigurationException;
+use TYPO3\CMS\Core\Security\BlockSerializationTrait;
 
 /**
  * Abstract implementation of a log writer
  */
 abstract class AbstractWriter implements WriterInterface
 {
+    use BlockSerializationTrait;
+
     /**
      * Constructs this log writer
      *
diff --git a/typo3/sysext/core/Classes/Mail/MemorySpool.php b/typo3/sysext/core/Classes/Mail/MemorySpool.php
index ef85b4cc90ef..057481d3a72f 100644
--- a/typo3/sysext/core/Classes/Mail/MemorySpool.php
+++ b/typo3/sysext/core/Classes/Mail/MemorySpool.php
@@ -23,6 +23,7 @@ use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
 use Symfony\Component\Mailer\SentMessage;
 use Symfony\Component\Mailer\Transport\AbstractTransport;
 use Symfony\Component\Mailer\Transport\TransportInterface;
+use TYPO3\CMS\Core\Security\BlockSerializationTrait;
 use TYPO3\CMS\Core\SingletonInterface;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 
@@ -38,6 +39,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
  */
 class MemorySpool extends AbstractTransport implements SingletonInterface, LoggerAwareInterface, DelayedTransportInterface
 {
+    use BlockSerializationTrait;
     use LoggerAwareTrait;
 
     /**
diff --git a/typo3/sysext/core/Classes/Security/BlockSerializationTrait.php b/typo3/sysext/core/Classes/Security/BlockSerializationTrait.php
new file mode 100644
index 000000000000..f4e39740a341
--- /dev/null
+++ b/typo3/sysext/core/Classes/Security/BlockSerializationTrait.php
@@ -0,0 +1,40 @@
+<?php
+
+declare(strict_types=1);
+
+/*
+ * 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!
+ */
+
+namespace TYPO3\CMS\Core\Security;
+
+/**
+ * Blocks object being using in `serialize()` and `unserialize()` invocations.
+ */
+trait BlockSerializationTrait
+{
+    /**
+     * Deny object serialization.
+     */
+    public function __sleep()
+    {
+        throw new \BadMethodCallException('Cannot serialize ' . __CLASS__, 1588784141);
+    }
+
+    /**
+     * Deny object deserialization.
+     */
+    public function __wakeup()
+    {
+        throw new \BadMethodCallException('Cannot unserialize ' . __CLASS__, 1588784142);
+    }
+}
diff --git a/typo3/sysext/core/Classes/Service/AbstractService.php b/typo3/sysext/core/Classes/Service/AbstractService.php
index db0b88f21113..0f89c57c668e 100644
--- a/typo3/sysext/core/Classes/Service/AbstractService.php
+++ b/typo3/sysext/core/Classes/Service/AbstractService.php
@@ -17,6 +17,7 @@ namespace TYPO3\CMS\Core\Service;
 
 use Psr\Log\LoggerAwareInterface;
 use Psr\Log\LoggerAwareTrait;
+use TYPO3\CMS\Core\Security\BlockSerializationTrait;
 use TYPO3\CMS\Core\TimeTracker\TimeTracker;
 use TYPO3\CMS\Core\Utility\CommandUtility;
 use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
@@ -27,6 +28,7 @@ use TYPO3\CMS\Core\Utility\GeneralUtility;
  */
 abstract class AbstractService implements LoggerAwareInterface
 {
+    use BlockSerializationTrait;
     use LoggerAwareTrait;
 
     // General error - something went wrong
diff --git a/typo3/sysext/extbase/Classes/Reflection/ReflectionService.php b/typo3/sysext/extbase/Classes/Reflection/ReflectionService.php
index 033cd5aa7d2a..2117d096d22b 100644
--- a/typo3/sysext/extbase/Classes/Reflection/ReflectionService.php
+++ b/typo3/sysext/extbase/Classes/Reflection/ReflectionService.php
@@ -18,6 +18,7 @@ namespace TYPO3\CMS\Extbase\Reflection;
 use TYPO3\CMS\Core\Cache\CacheManager;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Information\Typo3Version;
+use TYPO3\CMS\Core\Security\BlockSerializationTrait;
 use TYPO3\CMS\Core\SingletonInterface;
 use TYPO3\CMS\Extbase\Reflection\Exception\UnknownClassException;
 
@@ -27,6 +28,8 @@ use TYPO3\CMS\Extbase\Reflection\Exception\UnknownClassException;
  */
 class ReflectionService implements SingletonInterface
 {
+    use BlockSerializationTrait;
+
     /**
      * @var string
      */
diff --git a/typo3/sysext/extensionmanager/Classes/Controller/UploadExtensionFileController.php b/typo3/sysext/extensionmanager/Classes/Controller/UploadExtensionFileController.php
index 5792d0f00be0..cd5396be8585 100644
--- a/typo3/sysext/extensionmanager/Classes/Controller/UploadExtensionFileController.php
+++ b/typo3/sysext/extensionmanager/Classes/Controller/UploadExtensionFileController.php
@@ -18,6 +18,7 @@ namespace TYPO3\CMS\Extensionmanager\Controller;
 use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
 use TYPO3\CMS\Core\Core\Environment;
 use TYPO3\CMS\Core\Messaging\FlashMessage;
+use TYPO3\CMS\Core\Security\BlockSerializationTrait;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Extbase\Mvc\Exception\StopActionException;
 use TYPO3\CMS\Extensionmanager\Domain\Repository\ExtensionRepository;
@@ -34,6 +35,8 @@ use TYPO3\CMS\Extensionmanager\Utility\FileHandlingUtility;
  */
 class UploadExtensionFileController extends AbstractController
 {
+    use BlockSerializationTrait;
+
     /**
      * @var ExtensionRepository
      */
diff --git a/typo3/sysext/install/Classes/Service/Session/FileSessionHandler.php b/typo3/sysext/install/Classes/Service/Session/FileSessionHandler.php
index 70ef12f3c5c7..3e42c916605c 100644
--- a/typo3/sysext/install/Classes/Service/Session/FileSessionHandler.php
+++ b/typo3/sysext/install/Classes/Service/Session/FileSessionHandler.php
@@ -17,6 +17,7 @@ declare(strict_types=1);
 
 namespace TYPO3\CMS\Install\Service\Session;
 
+use TYPO3\CMS\Core\Security\BlockSerializationTrait;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Install\Service\Exception;
 
@@ -26,6 +27,8 @@ use TYPO3\CMS\Install\Service\Exception;
  */
 class FileSessionHandler implements \SessionHandlerInterface
 {
+    use BlockSerializationTrait;
+
     /**
      * The path to our var/session/ folder (where we can write our sessions). Set in the
      * constructor.
diff --git a/typo3/sysext/install/Classes/Service/SessionService.php b/typo3/sysext/install/Classes/Service/SessionService.php
index fe6768e8a703..bd38e0fda3eb 100644
--- a/typo3/sysext/install/Classes/Service/SessionService.php
+++ b/typo3/sysext/install/Classes/Service/SessionService.php
@@ -19,6 +19,7 @@ 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\Security\BlockSerializationTrait;
 use TYPO3\CMS\Core\SingletonInterface;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
 use TYPO3\CMS\Install\Exception;
@@ -30,6 +31,7 @@ use TYPO3\CMS\Install\Service\Session\FileSessionHandler;
  */
 class SessionService implements SingletonInterface
 {
+    use BlockSerializationTrait;
     use CookieHeaderTrait;
 
     /**
-- 
GitLab