Fixed bug #12294: Unchecked URL-Redirect parameter in Front-End logon (thanks to...
authorOliver Hader <oliver.hader@typo3.org>
Wed, 28 Jul 2010 09:16:21 +0000 (09:16 +0000)
committerOliver Hader <oliver.hader@typo3.org>
Wed, 28 Jul 2010 09:16:21 +0000 (09:16 +0000)
git-svn-id: https://svn.typo3.org/TYPO3v4/Core/branches/TYPO3_4-2@8422 709f56b5-9817-0410-a4d7-c38de5d9e867

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

index a54ce1a..4ff4c9f 100755 (executable)
--- a/ChangeLog
+++ b/ChangeLog
@@ -22,6 +22,7 @@
        * Fixed bug #14712: The GET/POST variable mimeType is used to create the http header content-type without verification (thanks to Rupert Germann)
        * Fixed bug #14412: Field value added to foreign_table_where by replacing ###REC_FIELD_THE_FIELD_NAME### is not quoted (thanks to Helmut Hummel and Xavier Perseguers)
        * Fixed bug #14114: Core mailform is open to spam abuse (thanks to Lars Houmark)
+       * Fixed bug #12294: Unchecked URL-Redirect parameter in Front-End logon (thanks to Steffen Kamper and Helmut Hummel)
 
 2010-07-21  Ingo Renner  <ingo@typo3.org>
 
index 7a160d6..ca1bd98 100644 (file)
@@ -101,6 +101,7 @@ class tx_felogin_pi1 extends tslib_pibase {
                if ($this->conf['redirectMode'] && !$this->conf['redirectDisable']) {
                        $this->redirectUrl = $this->processRedirect();
                }
+               $this->redirectUrl = $this->validateRedirectUrl($this->redirectUrl);
 
 
                        // What to display
@@ -612,6 +613,81 @@ class tx_felogin_pi1 extends tslib_pibase {
        protected function getDisplayText($label, $stdWrapArray=array()) {
                return $this->flexFormValue($label,'s_messages') ? $this->cObj->stdWrap($this->flexFormValue($label,'s_messages'),$stdWrapArray) : $this->cObj->stdWrap($this->pi_getLL('ll_'.$label, '', 1), $stdWrapArray);
        }
+
+       /**
+        * Returns a valid and XSS cleaned url for redirect, checked against configuration "allowedRedirectHosts"
+        *
+        * @param string $url
+        * @return string cleaned referer or empty string if not valid
+        */
+       protected function validateRedirectUrl($url) {
+               $url = strval($url);
+               if ($url === '') {
+                       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 '';
+               }
+
+               if (!t3lib_div::isValidUrl($sanitizedUrl)) {
+                       t3lib_div::sysLog(sprintf($this->pi_getLL('noValidRedirectUrl'), $sanitizedUrl), 'felogin', t3lib_div::SYSLOG_SEVERITY_WARNING);
+                       return '';
+               }
+
+                       // Validate the URL:
+               if ($this->isInCurrentDomain($sanitizedUrl) || $this->isInLocalDomain($sanitizedUrl)) {
+                       return $sanitizedUrl;
+               }
+
+                       // URL is not allowed
+               t3lib_div::sysLog(sprintf($this->pi_getLL('noValidRedirectUrl'), $url), 'felogin', t3lib_div::SYSLOG_SEVERITY_WARNING);
+               return '';
+       }
+
+       /**
+        * Determines whether the URL is on the current host
+        * and belongs to the current TYPO3 installation.
+        *
+        * @param string $url URL to be checked
+        * @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);
+       }
+
+       /**
+        * 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
+        */
+       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;
+                               }
+                       }
+               }
+
+               return $result;
+       }
 }
 
 
index e4b6d46..39575f8 100644 (file)
@@ -44,6 +44,8 @@ We couldn't find a username for this email address and so cannot send the passwo
                        <label index="ll_forgot_message">Please enter the email address by which you registered your user account. Then press &quot;Send password&quot; and your password will immediately be emailed to you. Make sure to spell your email address correctly.</label>
                        <label index="ll_forgot_message_emailSent">Your password has now been sent to the email address %s</label>
                        <label index="ll_forgot_header_backToLogin">Return to login form</label>
+                       <label index="noValidRedirectUrl">Url "%s" for redirect was not accepted!</label>
+                       <label index="xssAttackDetected">Url "%s" contained an XSS attack and was cleaned!</label>
                </languageKey>
        </data>
 </T3locallang>