Skip to content
Snippets Groups Projects
Commit 2ad48527 authored by Jaime Pérez's avatar Jaime Pérez
Browse files

bugfix: Do not try to apply SSP's base URL if REQUEST_URI does not match.

It is possible that the current script ($_SERVER['SCRIPT_FILENAME']) is inside SimpleSAMLphp's 'www' directory. However, even if that's the case, we should not enforce our base URL (as set in the 'baseurlpath' configuration option) if the request URI ($_SERVER['REQUEST_URI']) does not contain the relative path to the script. This is the case of AuthMemCookie, for example, where accessing a random URL protected by Apache, leads to the execution of a SimpleSAMLphp script, where SimpleSAML\Utils\HTTP::getSelfURL() must not try to be smart when guessing the current URL.
parents 9c462677 2155d1ec
No related branches found
No related tags found
No related merge requests found
......@@ -729,11 +729,31 @@ class HTTP
{
$cfg = \SimpleSAML_Configuration::getInstance();
$baseDir = $cfg->getBaseDir();
$current_path = realpath($_SERVER['SCRIPT_FILENAME']);
$rel_path = str_replace($baseDir.'www'.DIRECTORY_SEPARATOR, '', $current_path);
if ($current_path == $rel_path) { // compare loosely ($current_path can be false)
// we were accessed from an external script, do not try to apply our base URL
$cur_path = realpath($_SERVER['SCRIPT_FILENAME']);
// find the path to the current script relative to the www/ directory of SimpleSAMLphp
$rel_path = str_replace($baseDir.'www'.DIRECTORY_SEPARATOR, '', $cur_path);
// convert that relative path to an HTTP query
$url_path = str_replace(DIRECTORY_SEPARATOR, '/', $rel_path);
// find where the relative path starts in the current request URI
$uri_pos = (!empty($url_path)) ? strpos($_SERVER['REQUEST_URI'], $url_path) : false;
if ($cur_path == $rel_path || $uri_pos === false) {
/*
* We were accessed from an external script. This can happen in the following cases:
*
* - $_SERVER['SCRIPT_FILENAME'] points to a script that doesn't exist. E.g. functional testing. In this
* case, realpath() returns false and str_replace an empty string, so we compare them loosely.
*
* - The URI requested does not belong to a script in the www/ directory of SimpleSAMLphp. In that case,
* removing SimpleSAMLphp's base dir from the current path yields the same path, so $cur_path and
* $rel_path are equal.
*
* - The request URI does not match the current script. Even if the current script is located in the www/
* directory of SimpleSAMLphp, the URI does not contain its relative path, and $uri_pos is false.
*
* It doesn't matter which one of those cases we have. We just know we can't apply our base URL to the
* current URI, so we need to build it back from the PHP environment.
*/
$protocol = 'http';
$protocol .= (self::getServerHTTPS()) ? 's' : '';
$protocol .= '://';
......@@ -743,10 +763,7 @@ class HTTP
return $protocol.$hostname.$port.$_SERVER['REQUEST_URI'];
}
$url = self::getBaseURL();
$rel_path = str_replace(DIRECTORY_SEPARATOR, '/', $rel_path);
$pos = strpos($_SERVER['REQUEST_URI'], $rel_path) + strlen($rel_path);
return $url.$rel_path.substr($_SERVER['REQUEST_URI'], $pos);
return self::getBaseURL().$rel_path.substr($_SERVER['REQUEST_URI'], $uri_pos + strlen($url_path));
}
......
......@@ -189,12 +189,24 @@ class HTTPTest extends \PHPUnit_Framework_TestCase
$this->assertTrue(HTTP::isHTTPS());
$this->assertEquals('https://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost());
// test a valid, full URL, based on a full URL in the configuration
// test a request URI that doesn't match the current script
$cfg = \SimpleSAML_Configuration::loadFromArray(array(
'baseurlpath' => 'https://example.com/simplesaml/',
'baseurlpath' => 'https://example.org/simplesaml/',
), '[ARRAY]', 'simplesaml');
$baseDir = $cfg->getBaseDir();
$_SERVER['SCRIPT_FILENAME'] = $baseDir.'www/module.php';
$this->setupEnvFromURL('http://www.example.com/protected/resource.asp?foo=bar');
$this->assertEquals('http://www.example.com/protected/resource.asp?foo=bar', HTTP::getSelfURL());
$this->assertEquals('http://www.example.com', HTTP::getSelfURLHost());
$this->assertEquals('http://www.example.com/protected/resource.asp', HTTP::getSelfURLNoQuery());
$this->assertFalse(HTTP::isHTTPS());
$this->assertEquals('example.org', HTTP::getSelfHostWithNonStandardPort());
$this->assertEquals('http://www.example.com', HTTP::getSelfURLHost());
// test a valid, full URL, based on a full URL in the configuration
\SimpleSAML_Configuration::loadFromArray(array(
'baseurlpath' => 'https://example.com/simplesaml/',
), '[ARRAY]', 'simplesaml');
$this->setupEnvFromURL('http://www.example.org/module.php/module/file.php?foo=bar');
$this->assertEquals(
'https://example.com/simplesaml/module.php/module/file.php?foo=bar',
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment