diff --git a/lib/thirdpartylibs.xml b/lib/thirdpartylibs.xml
index 7aa577f33fb..cb7e0729930 100644
--- a/lib/thirdpartylibs.xml
+++ b/lib/thirdpartylibs.xml
@@ -165,7 +165,7 @@
typo3
Typo3
GPL
- 4.7.15
+ 4.7.19
2.0+
diff --git a/lib/typo3/class.t3lib_div.php b/lib/typo3/class.t3lib_div.php
index 3a3ba920197..c5012a675f3 100644
--- a/lib/typo3/class.t3lib_div.php
+++ b/lib/typo3/class.t3lib_div.php
@@ -59,6 +59,17 @@ final class t3lib_div {
const SYSLOG_SEVERITY_ERROR = 3;
const SYSLOG_SEVERITY_FATAL = 4;
+ const ENV_TRUSTED_HOSTS_PATTERN_ALLOW_ALL = '.*';
+ const ENV_TRUSTED_HOSTS_PATTERN_SERVER_NAME = 'SERVER_NAME';
+
+ /**
+ * State of host header value security check
+ * in order to avoid unnecessary multiple checks during one request
+ *
+ * @var bool
+ */
+ static protected $allowHostHeaderValue = FALSE;
+
/**
* Singleton instances returned by makeInstance, using the class names as
* array keys
@@ -3570,6 +3581,12 @@ final class t3lib_div {
$retVal = $host;
}
}
+ if (!self::isAllowedHostHeaderValue($retVal)) {
+ throw new UnexpectedValueException(
+ 'The current host header value does not match the configured trusted hosts pattern! Check the pattern defined in $GLOBALS[\'TYPO3_CONF_VARS\'][\'SYS\'][\'trustedHostsPattern\'] and adapt it, if you want to allow the current host header \'' . $retVal . '\' for your installation.',
+ 1396795884
+ );
+ }
break;
// These are let through without modification
case 'HTTP_REFERER':
@@ -3690,6 +3707,51 @@ final class t3lib_div {
return $retVal;
}
+ /**
+ * Checks if the provided host header value matches the trusted hosts pattern.
+ * If the pattern is not defined (which only can happen early in the bootstrap), deny any value.
+ *
+ * @param string $hostHeaderValue HTTP_HOST header value as sent during the request (may include port)
+ * @return bool
+ */
+ static public function isAllowedHostHeaderValue($hostHeaderValue) {
+ if (self::$allowHostHeaderValue === TRUE) {
+ return TRUE;
+ }
+
+ // Allow all install tool requests
+ // We accept this risk to have the install tool always available
+ // Also CLI needs to be allowed as unfortunately AbstractUserAuthentication::getAuthInfoArray() accesses HTTP_HOST without reason on CLI
+ if (defined('TYPO3_REQUESTTYPE') && (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_INSTALL) || (TYPO3_REQUESTTYPE & TYPO3_REQUESTTYPE_CLI)) {
+ return self::$allowHostHeaderValue = TRUE;
+ }
+
+ // Deny the value if trusted host patterns is empty, which means we are early in the bootstrap
+ if (empty($GLOBALS['TYPO3_CONF_VARS']['SYS']['trustedHostsPattern'])) {
+ return FALSE;
+ }
+
+ if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['trustedHostsPattern'] === self::ENV_TRUSTED_HOSTS_PATTERN_ALLOW_ALL) {
+ self::$allowHostHeaderValue = TRUE;
+ } elseif ($GLOBALS['TYPO3_CONF_VARS']['SYS']['trustedHostsPattern'] === self::ENV_TRUSTED_HOSTS_PATTERN_SERVER_NAME) {
+ // Allow values that equal the server name
+ // Note that this is only secure if name base virtual host are configured correctly in the webserver
+ $defaultPort = self::getIndpEnv('TYPO3_SSL') ? '443' : '80';
+ $parsedHostValue = parse_url('http://' . $hostHeaderValue);
+ if (isset($parsedHostValue['port'])) {
+ self::$allowHostHeaderValue = ($parsedHostValue['host'] === $_SERVER['SERVER_NAME'] && (string)$parsedHostValue['port'] === $_SERVER['SERVER_PORT']);
+ } else {
+ self::$allowHostHeaderValue = ($hostHeaderValue === $_SERVER['SERVER_NAME'] && $defaultPort === $_SERVER['SERVER_PORT']);
+ }
+ } else {
+ // In case name based virtual hosts are not possible, we allow setting a trusted host pattern
+ // See https://typo3.org/teams/security/security-bulletins/typo3-core/typo3-core-sa-2014-001/ for further details
+ self::$allowHostHeaderValue = (bool)preg_match('/^' . $GLOBALS['TYPO3_CONF_VARS']['SYS']['trustedHostsPattern'] . '$/', $hostHeaderValue);
+ }
+
+ return self::$allowHostHeaderValue;
+ }
+
/**
* Gets the unixtime as milliseconds.
*
@@ -4846,15 +4908,7 @@ final class t3lib_div {
}
// Create new instance and call constructor with parameters
- if (func_num_args() > 1) {
- $constructorArguments = func_get_args();
- array_shift($constructorArguments);
-
- $reflectedClass = new ReflectionClass($finalClassName);
- $instance = $reflectedClass->newInstanceArgs($constructorArguments);
- } else {
- $instance = new $finalClassName;
- }
+ $instance = static::instantiateClass($finalClassName, func_get_args());
// Register new singleton instance
if ($instance instanceof t3lib_Singleton) {
@@ -4864,6 +4918,54 @@ final class t3lib_div {
return $instance;
}
+ /**
+ * Speed optimized alternative to ReflectionClass::newInstanceArgs()
+ *
+ * @param string $className Name of the class to instantiate
+ * @param array $arguments Arguments passed to self::makeInstance() thus the first one with index 0 holds the requested class name
+ * @return mixed
+ */
+ protected static function instantiateClass($className, $arguments) {
+ switch (count($arguments)) {
+ case 1:
+ $instance = new $className();
+ break;
+ case 2:
+ $instance = new $className($arguments[1]);
+ break;
+ case 3:
+ $instance = new $className($arguments[1], $arguments[2]);
+ break;
+ case 4:
+ $instance = new $className($arguments[1], $arguments[2], $arguments[3]);
+ break;
+ case 5:
+ $instance = new $className($arguments[1], $arguments[2], $arguments[3], $arguments[4]);
+ break;
+ case 6:
+ $instance = new $className($arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5]);
+ break;
+ case 7:
+ $instance = new $className($arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6]);
+ break;
+ case 8:
+ $instance = new $className($arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6], $arguments[7]);
+ break;
+ case 9:
+ $instance = new $className($arguments[1], $arguments[2], $arguments[3], $arguments[4], $arguments[5], $arguments[6], $arguments[7], $arguments[8]);
+ break;
+ default:
+ // The default case for classes with constructors that have more than 8 arguments.
+ // This will fail when one of the arguments shall be passed by reference.
+ // In case we really need to support this edge case, we can implement the solution from here: https://review.typo3.org/26344
+ $class = new ReflectionClass($className);
+ array_shift($arguments);
+ $instance = $class->newInstanceArgs($arguments);
+ return $instance;
+ }
+ return $instance;
+ }
+
/**
* Returns the class name for a new instance, taking into account the
* class-extension API.
@@ -5734,4 +5836,4 @@ final class t3lib_div {
}
}
-?>
\ No newline at end of file
+?>
diff --git a/lib/typo3/readme_moodle.txt b/lib/typo3/readme_moodle.txt
index 0e188da4154..246aebfe16b 100644
--- a/lib/typo3/readme_moodle.txt
+++ b/lib/typo3/readme_moodle.txt
@@ -1,4 +1,4 @@
-Description of Typo3 libraries (v 4.7.15) import into Moodle
+Description of Typo3 libraries (v 4.7.19) import into Moodle
Changes:
1/ hacked relative include of class.t3lib_utility_debug.php