diff --git a/src/Control/SAMLController.php b/src/Control/SAMLController.php index 85ddcc9..ad640ce 100644 --- a/src/Control/SAMLController.php +++ b/src/Control/SAMLController.php @@ -262,6 +262,16 @@ protected function getRedirect() return $this->redirect($this->getRequest()->getSession()->get('BackURL')); } + // In SAMLHelper, we use RelayState to convey BackURL because in a HTTP POST flow + // with lax or strict cookie security the session will not be there for us. RelayState + // will be reflected back in the acs POST request. + // Note if only assertion is signed, RelayState cannot be trusted. Prevent open relay + // as in https://github.com/SAML-Toolkits/php-saml#avoiding-open-redirect-attacks + $relayState = $this->owner->getRequest()->postVar('RelayState'); + if ($relayState && Director::is_site_url($relayState)) { + return $this->redirect($relayState); + } + // Spoofing attack, redirect to homepage instead of spoofing url if ($back && !Director::is_site_url($back)) { return $this->redirect(Director::absoluteBaseURL()); diff --git a/src/Helpers/SAMLHelper.php b/src/Helpers/SAMLHelper.php index 6993825..6681542 100644 --- a/src/Helpers/SAMLHelper.php +++ b/src/Helpers/SAMLHelper.php @@ -75,7 +75,8 @@ public function redirect(RequestHandler $requestHandler = null, HTTPRequest $req $additionalGetQueryParams = $this->getAdditionalGETQueryParameters(); try { - $auth->login(Director::absoluteBaseURL() . 'saml/', $additionalGetQueryParams); + // Use RelayState to convey BackURL (will be handled in SAMLController). + $auth->login($backURL, $additionalGetQueryParams); } catch (Exception $e) { /** @var LoggerInterface $logger */ $logger = Injector::inst()->get(LoggerInterface::class);