From 2b6a19eaee185ddc4a1745a113d7e025934cdf0b Mon Sep 17 00:00:00 2001
From: Alexander Opitz <opitz.alexander@googlemail.com>
Date: Fri, 16 Feb 2018 10:08:07 +0100
Subject: [PATCH] [TASK] Properly check for HTTPS

Take into account empty and "off" values for the HTTPS request variable
to support ISAPI with IIS.

Resolves: #81837
Releases: master, 8.7
Change-Id: I5937c506d3e36a2009a8da6e66724728654b4001
Reviewed-on: https://review.typo3.org/55750
Reviewed-by: Mathias Schreiber <mathias.schreiber@typo3.com>
Tested-by: Mathias Schreiber <mathias.schreiber@typo3.com>
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
---
 .../core/Classes/Http/NormalizedParams.php    |  6 +-
 .../core/Classes/Utility/GeneralUtility.php   |  5 +-
 .../Tests/Unit/Http/NormalizedParamsTest.php  | 71 +++++++++++++++++++
 3 files changed, 79 insertions(+), 3 deletions(-)

diff --git a/typo3/sysext/core/Classes/Http/NormalizedParams.php b/typo3/sysext/core/Classes/Http/NormalizedParams.php
index 63af1d859f6f..6731d67723a9 100644
--- a/typo3/sysext/core/Classes/Http/NormalizedParams.php
+++ b/typo3/sysext/core/Classes/Http/NormalizedParams.php
@@ -588,10 +588,12 @@ class NormalizedParams
         if ($configuredProxySSL === '*') {
             $configuredProxySSL = trim($typo3ConfVars['SYS']['reverseProxyIP'] ?? '');
         }
+        $httpsParam = (string)($serverParams['HTTPS'] ?? '');
         if (GeneralUtility::cmpIP(trim($serverParams['REMOTE_ADDR'] ?? ''), $configuredProxySSL)
             || ($serverParams['SSL_SESSION_ID'] ?? '')
-            || strtolower($serverParams['HTTPS'] ?? '') === 'on'
-            || (string)($serverParams['HTTPS'] ?? '') === '1'
+            // https://secure.php.net/manual/en/reserved.variables.server.php
+            // "Set to a non-empty value if the script was queried through the HTTPS protocol."
+            || ($httpsParam !== '' && $httpsParam !== 'off' && $httpsParam !== '0')
         ) {
             $isHttps = true;
         }
diff --git a/typo3/sysext/core/Classes/Utility/GeneralUtility.php b/typo3/sysext/core/Classes/Utility/GeneralUtility.php
index fc14c97df056..5e9a2578f42e 100644
--- a/typo3/sysext/core/Classes/Utility/GeneralUtility.php
+++ b/typo3/sysext/core/Classes/Utility/GeneralUtility.php
@@ -2777,7 +2777,10 @@ class GeneralUtility
                 if (self::cmpIP($_SERVER['REMOTE_ADDR'], $proxySSL)) {
                     $retVal = true;
                 } else {
-                    $retVal = $_SERVER['SSL_SESSION_ID'] || strtolower($_SERVER['HTTPS']) === 'on' || (string)$_SERVER['HTTPS'] === '1';
+                    // https://secure.php.net/manual/en/reserved.variables.server.php
+                    // "Set to a non-empty value if the script was queried through the HTTPS protocol."
+                    $retVal = $_SERVER['SSL_SESSION_ID']
+                        || (!empty($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off');
                 }
                 break;
             case '_ARRAY':
diff --git a/typo3/sysext/core/Tests/Unit/Http/NormalizedParamsTest.php b/typo3/sysext/core/Tests/Unit/Http/NormalizedParamsTest.php
index 72e6e22276dd..0e0354776527 100644
--- a/typo3/sysext/core/Tests/Unit/Http/NormalizedParamsTest.php
+++ b/typo3/sysext/core/Tests/Unit/Http/NormalizedParamsTest.php
@@ -190,6 +190,32 @@ class NormalizedParamsTest extends UnitTestCase
                 [],
                 true,
             ],
+            'true if HTTPS is int(1)"' => [
+                [
+                    'HTTP_HOST' => 'www.domain.com',
+                    'HTTPS' => 1,
+                ],
+                [],
+                true,
+            ],
+            'true if HTTPS is bool(true)' => [
+                [
+                    'HTTP_HOST' => 'www.domain.com',
+                    'HTTPS' => true,
+                ],
+                [],
+                true,
+            ],
+            // https://secure.php.net/manual/en/reserved.variables.server.php
+            // "Set to a non-empty value if the script was queried through the HTTPS protocol."
+            'true if HTTPS is "somethingrandom"' => [
+                [
+                    'HTTP_HOST' => 'www.domain.com',
+                    'HTTPS' => 'somethingrandom',
+                ],
+                [],
+                true,
+            ],
             'false if HTTPS is "0"' => [
                 [
                     'HTTP_HOST' => 'www.domain.com',
@@ -198,6 +224,22 @@ class NormalizedParamsTest extends UnitTestCase
                 [],
                 false,
             ],
+            'false if HTTPS is int(0)' => [
+                [
+                    'HTTP_HOST' => 'www.domain.com',
+                    'HTTPS' => 0,
+                ],
+                [],
+                false,
+            ],
+            'false if HTTPS is float(0)' => [
+                [
+                    'HTTP_HOST' => 'www.domain.com',
+                    'HTTPS' => 0.0,
+                ],
+                [],
+                false,
+            ],
             'false if HTTPS is not on' => [
                 [
                     'HTTP_HOST' => 'www.domain.com',
@@ -214,6 +256,35 @@ class NormalizedParamsTest extends UnitTestCase
                 [],
                 false,
             ],
+            'false if HTTPS is null' => [
+                [
+                    'HTTP_HOST' => 'www.domain.com',
+                    'HTTPS' => null,
+                ],
+                [],
+                false,
+            ],
+            'false if HTTPS is bool(false)' => [
+                [
+                    'HTTP_HOST' => 'www.domain.com',
+                    'HTTPS' => false,
+                ],
+                [],
+                false,
+            ],
+            // Per PHP documententation 'HTTPS' is:
+            //   "Set to a non-empty value if the script
+            //   was queried through the HTTPS protocol."
+            // So theoretically an empty array means HTTPS is off.
+            // We do not support that. Therefore this test is disabled.
+            //'false if HTTPS is an empty Array' => [
+            //    [
+            //        'HTTP_HOST' => 'www.domain.com',
+            //        'HTTPS' => [],
+            //    ],
+            //    [],
+            //    false,
+            //],
             'true if ssl proxy IP matches REMOTE_ADDR' => [
                 [
                     'HTTP_HOST' => 'www.domain.com',
-- 
GitLab