diff --git a/lib/SimpleSAML/Utils/HTTP.php b/lib/SimpleSAML/Utils/HTTP.php index fa9b60028595db2cb9189d46b849aa64a200108a..257fdb57a38a65b9edfe4892c027d950d8e6189c 100644 --- a/lib/SimpleSAML/Utils/HTTP.php +++ b/lib/SimpleSAML/Utils/HTTP.php @@ -125,6 +125,27 @@ class HTTP } + /** + * Verify that a given URL is valid. + * + * @param string $url The URL we want to verify. + * + * @return boolean True if the given URL is valid, false otherwise. + */ + public static function isValidURL($url) + { + $url = filter_var($url, FILTER_VALIDATE_URL); + if ($url === false) { + return false; + } + $scheme = parse_url($url, PHP_URL_SCHEME); + if ($scheme !== false && in_array(strtolower($scheme), ['http', 'https'], true)) { + return true; + } + return false; + } + + /** * This function redirects the user to the specified address. * @@ -143,6 +164,7 @@ class HTTP * * @return void This function never returns. * @throws \InvalidArgumentException If $url is not a string or is empty, or $parameters is not an array. + * @throws \SimpleSAML\Error\Exception If $url is not a valid HTTP URL. * * @author Olav Morken, UNINETT AS <olav.morken@uninett.no> * @author Mads Freek Petersen @@ -153,6 +175,10 @@ class HTTP if (!is_string($url) || empty($url) || !is_array($parameters)) { throw new \InvalidArgumentException('Invalid input parameters.'); } + if (!self::isValidURL($url)) { + throw new Error\Exception('Invalid destination URL.'); + } + if (!empty($parameters)) { $url = self::addURLParameters($url, $parameters); } @@ -329,7 +355,7 @@ class HTTP } $url = self::normalizeURL($url); - if (filter_var($url, FILTER_VALIDATE_URL) === false) { + if (!self::isValidURL($url)) { throw new Error\Exception('Invalid URL: '.$url); } @@ -634,7 +660,7 @@ class HTTP */ $c = $globalConfig->toArray(); $c['baseurlpath'] = self::guessBasePath(); - throw new \SimpleSAML\Error\CriticalConfigurationError( + throw new Error\CriticalConfigurationError( 'Invalid value for \'baseurlpath\' in config.php. Valid format is in the form: '. '[(http|https)://(hostname|fqdn)[:port]]/[path/to/simplesaml/]. It must end with a \'/\'.', null, @@ -1144,9 +1170,9 @@ class HTTP // Do not set secure cookie if not on HTTPS if ($params['secure'] && !self::isHTTPS()) { if ($throw) { - throw new \SimpleSAML\Error\CannotSetCookie( + throw new Error\CannotSetCookie( 'Setting secure cookie on plain HTTP is not allowed.', - \SimpleSAML\Error\CannotSetCookie::SECURE_COOKIE + Error\CannotSetCookie::SECURE_COOKIE ); } Logger::warning('Error setting cookie: setting secure cookie on plain HTTP is not allowed.'); @@ -1187,9 +1213,9 @@ class HTTP if (!$success) { if ($throw) { - throw new \SimpleSAML\Error\CannotSetCookie( + throw new Error\CannotSetCookie( 'Headers already sent.', - \SimpleSAML\Error\CannotSetCookie::HEADERS_SENT + Error\CannotSetCookie::HEADERS_SENT ); } Logger::warning('Error setting cookie: headers already sent.'); @@ -1206,6 +1232,7 @@ class HTTP * @param array $data An associative array with the data to be posted to $destination. * * @throws \InvalidArgumentException If $destination is not a string or $data is not an array. + * @throws \SimpleSAML\Error\Exception If $destination is not a valid HTTP URL. * * @return void * @@ -1218,6 +1245,9 @@ class HTTP if (!is_string($destination) || !is_array($data)) { throw new \InvalidArgumentException('Invalid input parameters.'); } + if (!self::isValidURL($destination)) { + throw new Error\Exception('Invalid destination URL.'); + } $config = Configuration::getInstance(); $allowed = $config->getBoolean('enable.http_post', false); diff --git a/modules/core/www/postredirect.php b/modules/core/www/postredirect.php index a748eea8272995f9056235fcf906d565bdfbadd7..aa4ec28e50a3f50c2162956033c4e5f57aeca3ff 100644 --- a/modules/core/www/postredirect.php +++ b/modules/core/www/postredirect.php @@ -44,6 +44,10 @@ assert(is_array($postData)); assert(array_key_exists('url', $postData)); assert(array_key_exists('post', $postData)); +if (!\SimpleSAML\Utils\HTTP::isValidURL($destination)) { + throw new \SimpleSAML\Error\Exception('Invalid destination URL.'); +} + $config = \SimpleSAML\Configuration::getInstance(); $template = new \SimpleSAML\XHTML\Template($config, 'post.php'); $template->data['destination'] = $postData['url'];