Skip to content
Snippets Groups Projects
Commit dada996c authored by Olav Morken's avatar Olav Morken
Browse files

Add initial support for limiting redirect to trusted hosts.

Thanks to Daniel Tsosie for implementing this!

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@3233 44740490-163a-0410-bde0-09ae8108e29a
parent f3e5ae28
No related branches found
No related tags found
No related merge requests found
......@@ -668,4 +668,14 @@ $config = array (
*/
'proxy' => NULL,
/*
* Array of URL's to allow a trusted redirect to.
*
* Set to NULL to disable.
*
* Example:
* 'redirect.trustedsites' => array('sp.example.com', 'othersite.org'),
*/
'redirect.trustedsites' => NULL,
);
......@@ -251,7 +251,7 @@ class SimpleSAML_Auth_Default {
$session = SimpleSAML_Session::getInstance();
$session->doLogin($authId, self::extractPersistentAuthState($state));
SimpleSAML_Utilities::redirect($redirectTo);
SimpleSAML_Utilities::redirectUntrustedURL($redirectTo);
}
}
......
......@@ -563,14 +563,20 @@ class SimpleSAML_Utilities {
* will be urlencoded. If the value is NULL, then the
* parameter will be encoded as just the name, without a
* value.
* $allowed_redirect_hosts
* Array whitelist of hosts that redirects are allowed for.
* If NULL value, redirect will be allowed to any host.
* Otherwise, $url host must be present in Array for redirect.
* If the host is not present, an exception will be thrown.
*
* Returns:
* This function never returns.
*/
public static function redirect($url, $parameters = array()) {
public static function redirect($url, $parameters = array(), $allowed_redirect_hosts = NULL) {
assert(is_string($url));
assert(strlen($url) > 0);
assert(is_array($parameters));
if($allowed_redirect_hosts != NULL) assert(is_array($allowed_redirect_hosts));
/* Check for relative URL. */
if(substr($url, 0, 1) === '/') {
......@@ -585,6 +591,17 @@ class SimpleSAML_Utilities {
throw new SimpleSAML_Error_Exception('Redirect to invalid URL: ' . $url);
}
/* Validates that URL host is among those allowed. */
if ($allowed_redirect_hosts != NULL) {
preg_match('@^https?://([^/]+)@i', $url, $matches);
$hostname = $matches[1];
/* Throw exception for redirect to untrusted site */
if(!in_array($hostname, $allowed_redirect_hosts)) {
throw new SimpleSAML_Error_Exception('Redirect not to allowed redirect host: ' . $url);
}
}
/* Determine which prefix we should put before the first
* parameter.
*/
......@@ -667,6 +684,26 @@ class SimpleSAML_Utilities {
exit;
}
/*
* This function validates untrusted url has hostname against
* config option 'redirect.trustedsites'.
*
* If option not set or hostname present among trusted sites,
* peforms redirect via function redirect above.
*
* If site is not trusted, an exception will be thrown.
*
* See function redirect for details on url, parameters and return.
*/
public static function redirectUntrustedURL($url, $parameters = array()) {
$redirectTrustedSites = SimpleSAML_Configuration::getInstance()->getArray('redirect.trustedsites', NULL);
try {
self::redirect($url, $parameters, $redirectTrustedSites);
}
catch (SimpleSAML_Error_Exception $e) {
throw new SimpleSAML_Error_Exception('Site not in redirect.trusted sites: ' . $url);
}
}
/**
* This function transposes a two-dimensional array, so that
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment