diff --git a/README.md b/README.md index 26096ba..4e795fd 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ docker run --name ssp-casserver-dev \ --mount type=bind,source="$(pwd)/docker/ssp/authsources.php",target=/var/simplesamlphp/config/authsources.php,readonly \ --mount type=bind,source="$(pwd)/docker/ssp/config-override.php",target=/var/simplesamlphp/config/config-override.php,readonly \ --mount type=bind,source="$(pwd)/docker/apache-override.cf",target=/etc/apache2/sites-enabled/ssp-override.cf,readonly \ - -p 443:443 cirrusid/simplesamlphp:v2.3.5 + -p 443:443 cirrusid/simplesamlphp:v2.4.2 ``` Visit [https://localhost/simplesaml/](https://localhost/simplesaml/) and confirm you get the default page. diff --git a/composer.json b/composer.json index 1f17a12..8dd6294 100644 --- a/composer.json +++ b/composer.json @@ -30,13 +30,14 @@ }, "require": { "php": "^8.1", + "ext-ctype": "*", "ext-dom": "*", "ext-filter": "*", "ext-libxml": "*", "ext-SimpleXML": "*", "ext-session": "*", - "simplesamlphp/assert": "~1.8.2", + "simplesamlphp/assert": "~1.8.1", "simplesamlphp/composer-module-installer": "~1.4.0", "simplesamlphp/simplesamlphp": "~2.4.2", "simplesamlphp/xml-cas": "~1.3", diff --git a/src/Cas/ServiceValidator.php b/src/Cas/ServiceValidator.php index d3cb673..8caa4dd 100644 --- a/src/Cas/ServiceValidator.php +++ b/src/Cas/ServiceValidator.php @@ -53,35 +53,9 @@ public function checkServiceURL(string $service): ?Configuration $configOverride = \is_int($index) ? null : $value; - // URL String - if (str_starts_with($service, $legalUrl)) { - $isValidService = true; + if ($isValidService = $this->validateServiceIsLegal($legalUrl, $service)) { break; } - - // Regex - // Since "If the regex pattern passed does not compile to a valid regex, an E_WARNING is emitted. " - // we will throw an exception if the warning is emitted and use try-catch to handle it - set_error_handler(static function ($severity, $message, $file, $line) { - throw new \ErrorException($message, $severity, $severity, $file, $line); - }, E_WARNING); - - try { - $result = preg_match($legalUrl, $service); - if ($result !== 1) { - throw new \RuntimeException('Service URL does not match legal service URL.'); - } - $isValidService = true; - break; - } catch (\RuntimeException $e) { - // do nothing - Logger::warning($e->getMessage()); - } catch (\Exception $e) { - // do nothing - Logger::warning("Invalid CAS legal service url '$legalUrl'. Error " . preg_last_error()); - } finally { - restore_error_handler(); - } } if (!$isValidService) { @@ -107,4 +81,38 @@ public function checkServiceURL(string $service): ?Configuration } return Configuration::loadFromArray($serviceConfig); } + + /** + * @param string $legalUrl The string or regex to use for comparison + * @param string $service The service to compare + * + * @return bool Whether the service is legal + * @throws \ErrorException + */ + protected function validateServiceIsLegal(string $legalUrl, string $service): bool + { + $isValid = false; + if (!ctype_alnum($legalUrl[0])) { + // Since "If the regex pattern passed does not compile to a valid regex, an E_WARNING is emitted. " + // we will throw an exception if the warning is emitted and use try-catch to handle it + set_error_handler(static function ($severity, $message, $file, $line) { + throw new \ErrorException($message, $severity, $severity, $file, $line); + }, E_WARNING); + + try { + if (preg_match($legalUrl, $service) === 1) { + $isValid = true; + } + } catch (\ErrorException $e) { + // do nothing + Logger::warning("Invalid CAS legal service url '$legalUrl'. Error " . preg_last_error_msg()); + } finally { + restore_error_handler(); + } + } elseif (str_starts_with($service, $legalUrl)) { + $isValid = true; + } + + return $isValid; + } }