[TASK] Anonymize token in Exception handlers 86/56386/6
authorMathias Schreiber <mathias.schreiber@typo3.org>
Wed, 21 Mar 2018 07:01:00 +0000 (08:01 +0100)
committerMarkus Klein <markus.klein@typo3.org>
Thu, 22 Mar 2018 08:36:05 +0000 (09:36 +0100)
Log entries no longer contain specific tokens.
Instead, they are replaced with `--AnonymizedToken—`.

Resolves: #84502
Releases: master, 8.7
Change-Id: I42a8127cdccc904e8bbb82b5ea74b0e3d012586f
Reviewed-on: https://review.typo3.org/56386
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Georg Ringer <georg.ringer@gmail.com>
Tested-by: Georg Ringer <georg.ringer@gmail.com>
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Markus Klein <markus.klein@typo3.org>
typo3/sysext/core/Classes/Error/AbstractExceptionHandler.php
typo3/sysext/core/Tests/Unit/Core/ApplicationContextTest.php
typo3/sysext/core/Tests/Unit/Error/AbstractExceptionHandlerTest.php [new file with mode: 0644]

index d145f7d..2b7549a 100644 (file)
@@ -19,6 +19,7 @@ use Psr\Log\LoggerAwareTrait;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\SingletonInterface;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
+use TYPO3\CMS\Core\Utility\HttpUtility;
 
 /**
  * An abstract exception handler
@@ -68,7 +69,7 @@ abstract class AbstractExceptionHandler implements ExceptionHandlerInterface, Si
         $logMessage = 'Uncaught TYPO3 Exception: ' . $exceptionCodeNumber . $exception->getMessage() . ' | '
             . get_class($exception) . ' thrown in file ' . $filePathAndName . ' in line ' . $exception->getLine();
         if ($context === 'WEB') {
-            $logMessage .= '. Requested URL: ' . GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL');
+            $logMessage .= '. Requested URL: ' . $this->anonymizeToken(GeneralUtility::getIndpEnv('TYPO3_REQUEST_URL'));
         }
         // When database credentials are wrong, the exception is probably
         // caused by this. Therefor we cannot do any database operation,
@@ -141,7 +142,7 @@ abstract class AbstractExceptionHandler implements ExceptionHandlerInterface, Si
         if (method_exists($exception, 'getStatusHeaders')) {
             $headers = $exception->getStatusHeaders();
         } else {
-            $headers = [\TYPO3\CMS\Core\Utility\HttpUtility::HTTP_STATUS_500];
+            $headers = [HttpUtility::HTTP_STATUS_500];
         }
         if (!headers_sent()) {
             foreach ($headers as $header) {
@@ -157,4 +158,16 @@ abstract class AbstractExceptionHandler implements ExceptionHandlerInterface, Si
     {
         return $GLOBALS['BE_USER'];
     }
+
+    /**
+     * Replaces the generated token with a generic equivalent
+     *
+     * @param string $requestedUrl
+     * @return string
+     */
+    protected function anonymizeToken(string $requestedUrl): string
+    {
+        $pattern = '/(?<=[tT]oken=)[0-9a-fA-F]{40}/';
+        return preg_replace($pattern, '--AnonymizedToken--', $requestedUrl);
+    }
 }
index c8c11a1..64a041b 100644 (file)
@@ -1,15 +1,18 @@
 <?php
 namespace TYPO3\CMS\Core\Tests\Unit\Core;
 
-/*                                                                        *
- * This script belongs to the TYPO3 Flow framework.                       *
- *                                                                        *
- * It is free software; you can redistribute it and/or modify it under    *
- * the terms of the GNU Lesser General Public License, either version 3   *
- * of the License, or (at your option) any later version.                 *
- *                                                                        *
- * The TYPO3 project - inspiring people to share!                         *
- *                                                                        */
+/*
+ * 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 TYPO3\CMS\Core\Core\ApplicationContext;
 
diff --git a/typo3/sysext/core/Tests/Unit/Error/AbstractExceptionHandlerTest.php b/typo3/sysext/core/Tests/Unit/Error/AbstractExceptionHandlerTest.php
new file mode 100644 (file)
index 0000000..531eb21
--- /dev/null
@@ -0,0 +1,69 @@
+<?php
+declare(strict_types=1);
+namespace TYPO3\CMS\Core\Tests\Unit\Error;
+
+/*
+ * 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 TYPO3\CMS\Core\Error\AbstractExceptionHandler;
+use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
+
+/**
+ * Testcase for the AbstractExceptionHandlerTest class
+ */
+class AbstractExceptionHandlerTest extends UnitTestCase
+{
+    /**
+     * Data provider with allowed contexts.
+     *
+     * @return array
+     */
+    public function exampleUrlsForTokenAnonymization(): array
+    {
+        return [
+            'url with valid token' => [
+                'http://localhost/typo3/index.php?M=foo&moduleToken=5f1f7d447f22886e8ea206693b0d530ccd6b2b36',
+                'http://localhost/typo3/index.php?M=foo&moduleToken=--AnonymizedToken--'
+            ],
+            'url with valid token in the middle' => [
+                'http://localhost/typo3/index.php?M=foo&moduleToken=5f1f7d447f22886e8ea206693b0d530ccd6b2b36&param=asdf',
+                'http://localhost/typo3/index.php?M=foo&moduleToken=--AnonymizedToken--&param=asdf'
+            ],
+            'url with invalid token' => [
+                'http://localhost/typo3/index.php?M=foo&moduleToken=5f1f7d447f22886e8/e',
+                'http://localhost/typo3/index.php?M=foo&moduleToken=5f1f7d447f22886e8/e',
+            ],
+            'url with empty token' => [
+                'http://localhost/typo3/index.php?M=foo&moduleToken=',
+                'http://localhost/typo3/index.php?M=foo&moduleToken=',
+            ],
+            'url with no token' => [
+                'http://localhost/typo3/index.php?M=foo',
+                'http://localhost/typo3/index.php?M=foo',
+            ],
+        ];
+    }
+
+    /**
+     * @test
+     * @dataProvider exampleUrlsForTokenAnonymization
+     * @param string $originalUrl
+     * @param string $expectedUrl
+     */
+    public function anonymizeTokenReturnsCorrectModifiedUrl(string $originalUrl, string $expectedUrl)
+    {
+        $mock = $this->getAccessibleMockForAbstractClass(AbstractExceptionHandler::class, ['dummy']);
+        $anonymizedUrl = $mock->_call('anonymizeToken', $originalUrl);
+        $this->assertSame($expectedUrl, $anonymizedUrl);
+    }
+}