Index: t3lib/class.t3lib_div.php =================================================================== --- t3lib/class.t3lib_div.php (Revision 8444) +++ t3lib/class.t3lib_div.php (Arbeitskopie) @@ -826,6 +826,17 @@ } /** + * Checks if a given URL matches the host that currently handles this HTTP request. + * Scheme, hostname and (optional) port of the given URL are compared. + * + * @param string $url: URL to compare with the TYPO3 request host + * @return boolean Whether the URL matches the TYPO3 request host + */ + function isOnCurrentHost($url) { + return (stripos(strtolower($url) . '/', strtolower(t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST')) . '/') === 0); + } + + /** * Check for item in list * Check if an item exists in a comma-separated list of items. * Usage: 163 @@ -3579,16 +3590,60 @@ * Checks if a given string is a valid frame URL to be loaded in the * backend. * - * This is a wrapper for sanitizeBackEndUrl() which only exists in TYPO3 4.1. - * Since TYPO3 4.2 the method is called sanitizeLocalUrl(). - * * @param string $url potential URL to check * * @return string either $url if $url is considered to be harmless, or an * empty string otherwise */ function sanitizeLocalUrl($url = '') { - return t3lib_div::sanitizeBackEndUrl($url); + $sanitizedUrl = ''; + + $decodedUrl = rawurldecode($url); + $decodedParts = @parse_url($decodedUrl); + + $whitelistPattern = '/^(\p{Nd}|\p{L}|[_\/\.&=\?-])+$/u'; + + // An valid URL must at least have the path part: + if (isset($decodedParts['path'])) { + // Check all URL parts for invalid characters: + foreach ($decodedParts as $part) { + if (!preg_match($whitelistPattern, $part)) { + $url = ''; + break; + } + } + } else { + $url = ''; + } + + if (!empty($url)) { + $testAbsoluteUrl = t3lib_div::resolveBackPath($decodedUrl); + $testRelativeUrl = t3lib_div::resolveBackPath( + t3lib_div::dirname(t3lib_div::getIndpEnv('SCRIPT_NAME')) . '/' . $decodedUrl + ); + + // Pass if URL is on the current host: + if (isset($decodedParts['scheme']) && isset($decodedParts['host'])) { + if (t3lib_div::isOnCurrentHost($decodedUrl) && strpos($decodedUrl, t3lib_div::getIndpEnv('TYPO3_SITE_URL')) === 0) { + $sanitizedUrl = $url; + } + // Pass if URL is an absolute file path: + } elseif (t3lib_div::isAbsPath($decodedUrl) && t3lib_div::isAllowedAbsPath($decodedUrl)) { + $sanitizedUrl = $url; + // Pass if URL is absolute and below TYPO3 base directory: + } elseif (strpos($testAbsoluteUrl, t3lib_div::getIndpEnv('TYPO3_SITE_PATH')) === 0 && substr($decodedUrl, 0, 1) === '/') { + $sanitizedUrl = $url; + // Pass if URL is relative and below TYPO3 base directory: + } elseif (strpos($testRelativeUrl, t3lib_div::getIndpEnv('TYPO3_SITE_PATH')) === 0 && substr($decodedUrl, 0, 1) !== '/') { + $sanitizedUrl = $url; + } + } + + if (!empty($url) && empty($sanitizedUrl)) { + t3lib_div::sysLog('The URL "' . $url . '" is not considered to be local and was denied.', 'Core', 1); + } + + return $sanitizedUrl; } /** Index: typo3/tce_db.php =================================================================== --- typo3/tce_db.php (Revision 8444) +++ typo3/tce_db.php (Arbeitskopie) @@ -112,7 +112,7 @@ $this->cmd = t3lib_div::_GP('cmd'); $this->mirror = t3lib_div::_GP('mirror'); $this->cacheCmd = t3lib_div::_GP('cacheCmd'); - $this->redirect = t3lib_div::sanitizeBackEndUrl(t3lib_div::_GP('redirect')); + $this->redirect = t3lib_div::sanitizeLocalUrl(t3lib_div::_GP('redirect')); $this->prErr = t3lib_div::_GP('prErr'); $this->_disableRTE = t3lib_div::_GP('_disableRTE'); $this->CB = t3lib_div::_GP('CB'); Index: typo3/logout.php =================================================================== --- typo3/logout.php (Revision 8444) +++ typo3/logout.php (Arbeitskopie) @@ -72,7 +72,7 @@ $BE_USER->writelog(255,2,0,1,'User %s logged out from TYPO3 Backend',Array($BE_USER->user['username'])); // Logout written to log $BE_USER->logoff(); - $redirect = t3lib_div::sanitizeBackEndUrl(t3lib_div::_GP('redirect')); + $redirect = t3lib_div::sanitizeLocalUrl(t3lib_div::_GP('redirect')); $redirectUrl = $redirect ? $redirect : 'index.php'; header('Location: '.t3lib_div::locationHeaderUrl($redirectUrl));