Fixed bug #15280: felogin redirect doesn't work anymore after update to latest releas...
authorOliver Hader <oliver.hader@typo3.org>
Thu, 5 Aug 2010 16:21:40 +0000 (16:21 +0000)
committerOliver Hader <oliver.hader@typo3.org>
Thu, 5 Aug 2010 16:21:40 +0000 (16:21 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/branches/TYPO3_4-2@8485 709f56b5-9817-0410-a4d7-c38de5d9e867

ChangeLog
typo3/sysext/felogin/pi1/class.tx_felogin_pi1.php

index 334fcd7..f372435 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2010-08-05  Oliver Hader  <oliver@typo3.org>
+
+       * Fixed bug #15280: felogin redirect doesn't work anymore after update to latest releases (4.2x - 4.4.x) (thanks to Helmut Hummel)
+
 2010-08-03  Oliver Hader  <oliver@typo3.org>
 
        * Fixed bug #15265: InstallTool-login not possible after Update to 4.4.1 due to session_start() in extensions (thanks to Ernesto Baschny and Helmut Hummel)
index ca1bd98..dd14207 100644 (file)
@@ -626,20 +626,17 @@ class tx_felogin_pi1 extends tslib_pibase {
                        return '';
                }
 
-               $sanitizedUrl = t3lib_div::removeXSS(rawurldecode($url));
-               if ($url !== $sanitizedUrl) {
-                       t3lib_div::sysLog(sprintf($this->pi_getLL('xssAttackDetected'), $url), 'felogin', t3lib_div::SYSLOG_SEVERITY_WARNING);
-                       return '';
-               }
+               $decodedUrl = rawurldecode($url);
+               $sanitizedUrl = t3lib_div::removeXSS($decodedUrl);
 
-               if (!t3lib_div::isValidUrl($sanitizedUrl)) {
-                       t3lib_div::sysLog(sprintf($this->pi_getLL('noValidRedirectUrl'), $sanitizedUrl), 'felogin', t3lib_div::SYSLOG_SEVERITY_WARNING);
+               if ($decodedUrl !== $sanitizedUrl || preg_match('#["<>\\\]+#', $url)) {
+                       t3lib_div::sysLog(sprintf($this->pi_getLL('xssAttackDetected'), $url), 'felogin', t3lib_div::SYSLOG_SEVERITY_WARNING);
                        return '';
                }
 
                        // Validate the URL:
-               if ($this->isInCurrentDomain($sanitizedUrl) || $this->isInLocalDomain($sanitizedUrl)) {
-                       return $sanitizedUrl;
+               if ($this->isRelativeUrl($url) || $this->isInCurrentDomain($url) || $this->isInLocalDomain($url)) {
+                       return $url;
                }
 
                        // URL is not allowed
@@ -655,39 +652,61 @@ class tx_felogin_pi1 extends tslib_pibase {
         * @return boolean Whether the URL belongs to the current TYPO3 installation
         */
        protected function isInCurrentDomain($url) {
-               return (t3lib_div::isOnCurrentHost($url) && strpos($url, t3lib_div::getIndpEnv('TYPO3_SITE_URL')) === 0);
+               return (t3lib_div::isOnCurrentHost($url) && t3lib_div::isFirstPartOfStr($url, t3lib_div::getIndpEnv('TYPO3_SITE_URL')));
        }
 
        /**
         * Determines whether the URL matches a domain
         * in the sys_domain databse table.
         *
-        * @param string $domain Name of the domain to be looked up
-        * @return boolean Whether the domain name is considered to be local
+        * @param string $url Absolute URL which needs to be checked
+        * @return boolean Whether the URL is considered to be local
         */
        protected function isInLocalDomain($url) {
                $result = FALSE;
 
-               $parsedUrl = parse_url($url);
-               $domain = $parsedUrl['host'] . $parsedUrl['path'];
-
-               $localDomains = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
-                       'domainName',
-                       'sys_domain',
-                       '1=1' . $this->cObj->enableFields('sys_domain')
-               );
-
-               if (is_array($localDomains)) {
-                       foreach ($localDomains as $localDomain) {
-                               if (stripos($domain, $localDomain['domainName']) === 0) {
-                                       $result = TRUE;
-                                       break;
+               if (t3lib_div::isValidUrl($url)) {
+                       $parsedUrl = parse_url($url);
+                       if ($parsedUrl['scheme'] === 'http' || $parsedUrl['scheme'] === 'https' ) {
+                               $host = $parsedUrl['host'];
+                                       // Removes the last path segment and slash sequences like /// (if given):
+                               $path = preg_replace('#/+[^/]*$#', '', $parsedUrl['path']);
+
+                               $localDomains = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
+                                       'domainName',
+                                       'sys_domain',
+                                       '1=1' . $this->cObj->enableFields('sys_domain')
+                               );
+                               if (is_array($localDomains)) {
+                                       foreach ($localDomains as $localDomain) {
+                                                       // strip trailing slashes (if given)
+                                               $domainName = rtrim($localDomain['domainName'], '/');
+                                               if (t3lib_div::isFirstPartOfStr($host. $path . '/', $domainName . '/')) {
+                                                       $result = TRUE;
+                                                       break;
+                                               }
+                                       }
                                }
                        }
                }
-
                return $result;
        }
+
+       /**
+        * Determines wether the URL is relative to the
+        * current TYPO3 installation.
+        *
+        * @param string $url URL which needs to be checked
+        * @return boolean Whether the URL is considered to be relative
+        */
+       protected function isRelativeUrl($url) {
+               $parsedUrl = @parse_url($url);
+               if ($parsedUrl !== FALSE && !isset($parsedUrl['scheme']) && !isset($parsedUrl['host'])) {
+                               // If the relative URL starts with a slash, we need to check if it's within the current site path
+                       return (!t3lib_div::isFirstPartOfStr($parsedUrl['path'], '/') || t3lib_div::isFirstPartOfStr($parsedUrl['path'], t3lib_div::getIndpEnv('TYPO3_SITE_PATH')));
+               }
+               return FALSE;
+       }
 }