-
Tim van Dijen authoreda3513e46
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
<?php
namespace SimpleSAML\Test\Utils;
use PHPUnit\Framework\TestCase;
use SimpleSAML\Utils\HTTP;
use SimpleSAML\Configuration;
class HTTPTest extends TestCase
{
/**
* Set up the environment ($_SERVER) populating the typical variables from a given URL.
*
* @param string $url The URL to use as the current one.
*/
private function setupEnvFromURL($url)
{
$addr = parse_url($url);
$_SERVER['HTTP_HOST'] = $addr['host'];
$_SERVER['SERVER_NAME'] = $addr['host'];
if ($addr['scheme'] === 'https') {
$_SERVER['HTTPS'] = 'on';
$default_port = '443';
} else {
unset($_SERVER['HTTPS']);
$default_port = '80';
}
$_SERVER['SERVER_PORT'] = $default_port;
if (isset($addr['port']) && strval($addr['port']) !== $default_port) {
$_SERVER['SERVER_PORT'] = strval($addr['port']);
}
$_SERVER['REQUEST_URI'] = $addr['path'].'?'.$addr['query'];
}
/**
* Test SimpleSAML\Utils\HTTP::addURLParameters().
*
* @expectedException \InvalidArgumentException
*/
public function testAddURLParametersInvalidURL()
{
HTTP::addURLParameters(array(), array());
}
/**
* Test SimpleSAML\Utils\HTTP::addURLParameters().
*
* @expectedException \InvalidArgumentException
*/
public function testAddURLParametersInvalidParameters()
{
HTTP::addURLParameters('string', 'string');
}
/**
* Test SimpleSAML\Utils\HTTP::addURLParameters().
*/
public function testAddURLParameters()
{
$url = 'http://example.com/';
$params = array(
'foo' => 'bar',
'bar' => 'foo',
);
$this->assertEquals($url.'?foo=bar&bar=foo', HTTP::addURLParameters($url, $params));
$url = 'http://example.com/?';
$params = array(
'foo' => 'bar',
'bar' => 'foo',
);
$this->assertEquals($url.'foo=bar&bar=foo', HTTP::addURLParameters($url, $params));
$url = 'http://example.com/?foo=bar';
$params = array(
'bar' => 'foo',
);
$this->assertEquals($url.'&bar=foo', HTTP::addURLParameters($url, $params));
}
/**
* Test SimpleSAML\Utils\HTTP::guessBasePath().
*/
public function testGuessBasePath()
{
$original = $_SERVER;
$_SERVER['REQUEST_URI'] = '/simplesaml/module.php';
$_SERVER['SCRIPT_FILENAME'] = '/some/path/simplesamlphp/www/module.php';
$this->assertEquals('/simplesaml/', HTTP::guessBasePath());
$_SERVER['REQUEST_URI'] = '/simplesaml/module.php/some/path/to/other/script.php';
$_SERVER['SCRIPT_FILENAME'] = '/some/path/simplesamlphp/www/module.php';
$this->assertEquals('/simplesaml/', HTTP::guessBasePath());
$_SERVER['REQUEST_URI'] = '/module.php';
$_SERVER['SCRIPT_FILENAME'] = '/some/path/simplesamlphp/www/module.php';
$this->assertEquals('/', HTTP::guessBasePath());
$_SERVER['REQUEST_URI'] = '/module.php/some/path/to/other/script.php';
$_SERVER['SCRIPT_FILENAME'] = '/some/path/simplesamlphp/www/module.php';
$this->assertEquals('/', HTTP::guessBasePath());
$_SERVER['REQUEST_URI'] = '/some/path/module.php';
$_SERVER['SCRIPT_FILENAME'] = '/some/path/simplesamlphp/www/module.php';
$this->assertEquals('/some/path/', HTTP::guessBasePath());
$_SERVER['REQUEST_URI'] = '/some/path/module.php/some/path/to/other/script.php';
$_SERVER['SCRIPT_FILENAME'] = '/some/path/simplesamlphp/www/module.php';
$this->assertEquals('/some/path/', HTTP::guessBasePath());
$_SERVER['REQUEST_URI'] = '/some/dir/in/www/script.php';
$_SERVER['SCRIPT_FILENAME'] = '/some/path/simplesamlphp/www/some/dir/in/www/script.php';
$this->assertEquals('/', HTTP::guessBasePath());
$_SERVER['REQUEST_URI'] = '/simplesaml/some/dir/in/www/script.php';
$_SERVER['SCRIPT_FILENAME'] = '/some/path/simplesamlphp/www/some/dir/in/www/script.php';
$this->assertEquals('/simplesaml/', HTTP::guessBasePath());
$_SERVER = $original;
}
/**
* Test SimpleSAML\Utils\HTTP::getSelfHost() with and without custom port.
*/
public function testGetSelfHost()
{
$original = $_SERVER;
Configuration::loadFromArray(array(
'baseurlpath' => '',
), '[ARRAY]', 'simplesaml');
$_SERVER['SERVER_PORT'] = '80';
$this->assertEquals('localhost', HTTP::getSelfHost());
$_SERVER['SERVER_PORT'] = '3030';
$this->assertEquals('localhost', HTTP::getSelfHost());
$_SERVER = $original;
}
/**
* Test SimpleSAML\Utils\HTTP::getSelfHostWithPort(), with and without custom port.
*/
public function testGetSelfHostWithPort()
{
$original = $_SERVER;
Configuration::loadFromArray(array(
'baseurlpath' => '',
), '[ARRAY]', 'simplesaml');
// standard port for HTTP
$_SERVER['SERVER_PORT'] = '80';
$this->assertEquals('localhost', HTTP::getSelfHostWithNonStandardPort());
// non-standard port
$_SERVER['SERVER_PORT'] = '3030';
$this->assertEquals('localhost:3030', HTTP::getSelfHostWithNonStandardPort());
// standard port for HTTPS
$_SERVER['HTTPS'] = 'on';
$_SERVER['SERVER_PORT'] = '443';
$this->assertEquals('localhost', HTTP::getSelfHostWithNonStandardPort());
$_SERVER = $original;
}
/**
* Test SimpleSAML\Utils\HTTP::getSelfURL().
*/
public function testGetSelfURLMethods()
{
$original = $_SERVER;
/*
* Test a URL pointing to a script that's not part of the public interface. This allows us to test calls to
* getSelfURL() from scripts outside of SimpleSAMLphp
*/
Configuration::loadFromArray(array(
'baseurlpath' => 'http://example.com/simplesaml/',
), '[ARRAY]', 'simplesaml');
$url = 'https://example.com/app/script.php/some/path?foo=bar';
$this->setupEnvFromURL($url);
$_SERVER['SCRIPT_FILENAME'] = '/var/www/app/script.php';
$this->assertEquals($url, HTTP::getSelfURL());
$this->assertEquals('https://example.com', HTTP::getSelfURLHost());
$this->assertEquals('https://example.com/app/script.php/some/path', HTTP::getSelfURLNoQuery());
$this->assertTrue(HTTP::isHTTPS());
$this->assertEquals('https://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost());
// test a request URI that doesn't match the current script
$cfg = Configuration::loadFromArray(array(
'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
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',
HTTP::getSelfURL()
);
$this->assertEquals('https://example.com', HTTP::getSelfURLHost());
$this->assertEquals('https://example.com/simplesaml/module.php/module/file.php', HTTP::getSelfURLNoQuery());
$this->assertTrue(HTTP::isHTTPS());
$this->assertEquals('https://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost());
// test a valid, full URL, based on a full URL *without* a trailing slash in the configuration
Configuration::loadFromArray(array(
'baseurlpath' => 'https://example.com/simplesaml',
), '[ARRAY]', 'simplesaml');
$this->assertEquals(
'https://example.com/simplesaml/module.php/module/file.php?foo=bar',
HTTP::getSelfURL()
);
$this->assertEquals('https://example.com', HTTP::getSelfURLHost());
$this->assertEquals('https://example.com/simplesaml/module.php/module/file.php', HTTP::getSelfURLNoQuery());
$this->assertTrue(HTTP::isHTTPS());
$this->assertEquals('https://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost());
// test a valid, full URL, based on a full URL *without* a path in the configuration
Configuration::loadFromArray(array(
'baseurlpath' => 'https://example.com',
), '[ARRAY]', 'simplesaml');
$this->assertEquals(
'https://example.com/module.php/module/file.php?foo=bar',
HTTP::getSelfURL()
);
$this->assertEquals('https://example.com', HTTP::getSelfURLHost());
$this->assertEquals('https://example.com/module.php/module/file.php', HTTP::getSelfURLNoQuery());
$this->assertTrue(HTTP::isHTTPS());
$this->assertEquals('https://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost());
// test a valid, full URL, based on a relative path in the configuration
Configuration::loadFromArray(array(
'baseurlpath' => '/simplesaml/',
), '[ARRAY]', 'simplesaml');
$this->setupEnvFromURL('http://www.example.org/simplesaml/module.php/module/file.php?foo=bar');
$this->assertEquals(
'http://www.example.org/simplesaml/module.php/module/file.php?foo=bar',
HTTP::getSelfURL()
);
$this->assertEquals('http://www.example.org', HTTP::getSelfURLHost());
$this->assertEquals('http://www.example.org/simplesaml/module.php/module/file.php', HTTP::getSelfURLNoQuery());
$this->assertFalse(HTTP::isHTTPS());
$this->assertEquals('http://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost());
// test a valid, full URL, based on a relative path in the configuration and a non standard port
Configuration::loadFromArray(array(
'baseurlpath' => '/simplesaml/',
), '[ARRAY]', 'simplesaml');
$this->setupEnvFromURL('http://example.org:8080/simplesaml/module.php/module/file.php?foo=bar');
$this->assertEquals(
'http://example.org:8080/simplesaml/module.php/module/file.php?foo=bar',
HTTP::getSelfURL()
);
$this->assertEquals('http://example.org:8080', HTTP::getSelfURLHost());
$this->assertEquals('http://example.org:8080/simplesaml/module.php/module/file.php', HTTP::getSelfURLNoQuery());
$this->assertFalse(HTTP::isHTTPS());
$this->assertEquals('http://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost());
// test a valid, full URL, based on a relative path in the configuration, a non standard port and HTTPS
Configuration::loadFromArray(array(
'baseurlpath' => '/simplesaml/',
), '[ARRAY]', 'simplesaml');
$this->setupEnvFromURL('https://example.org:8080/simplesaml/module.php/module/file.php?foo=bar');
$this->assertEquals(
'https://example.org:8080/simplesaml/module.php/module/file.php?foo=bar',
HTTP::getSelfURL()
);
$this->assertEquals('https://example.org:8080', HTTP::getSelfURLHost());
$this->assertEquals(
'https://example.org:8080/simplesaml/module.php/module/file.php',
HTTP::getSelfURLNoQuery()
);
$this->assertTrue(HTTP::isHTTPS());
$this->assertEquals('https://'.HTTP::getSelfHostWithNonStandardPort(), HTTP::getSelfURLHost());
$_SERVER = $original;
}
/**
* Test SimpleSAML\Utils\HTTP::checkURLAllowed(), without regex.
*/
public function testCheckURLAllowedWithoutRegex()
{
$original = $_SERVER;
Configuration::loadFromArray(array(
'trusted.url.domains' => array('sp.example.com', 'app.example.com'),
'trusted.url.regex' => false,
), '[ARRAY]', 'simplesaml');
$_SERVER['REQUEST_URI'] = '/module.php';
$allowed = array(
'https://sp.example.com/',
'http://sp.example.com/',
'https://app.example.com/',
'http://app.example.com/',
);
foreach ($allowed as $url) {
$this->assertEquals(HTTP::checkURLAllowed($url), $url);
}
$this->setExpectedException('\SimpleSAML\Error\Exception');
HTTP::checkURLAllowed('https://evil.com');
$_SERVER = $original;
}
/**
* Test SimpleSAML\Utils\HTTP::checkURLAllowed(), with regex.
*/
public function testCheckURLAllowedWithRegex()
{
$original = $_SERVER;
Configuration::loadFromArray(array(
'trusted.url.domains' => array('.*\.example\.com'),
'trusted.url.regex' => true,
), '[ARRAY]', 'simplesaml');
$_SERVER['REQUEST_URI'] = '/module.php';
$allowed = array(
'https://sp.example.com/',
'http://sp.example.com/',
'https://app1.example.com/',
'http://app1.example.com/',
'https://app2.example.com/',
'http://app2.example.com/',
);
foreach ($allowed as $url) {
$this->assertEquals(HTTP::checkURLAllowed($url), $url);
}
$this->setExpectedException('\SimpleSAML\Error\Exception');
HTTP::checkURLAllowed('https://evil.com');
$_SERVER = $original;
}
/**
* Test SimpleSAML\Utils\HTTP::getServerPort().
*/
public function testGetServerPort()
{
$original = $_SERVER;
// Test HTTP + non-standard port
$_SERVER['HTTPS'] = 'off';
$_SERVER['SERVER_PORT'] = '3030';
$this->assertEquals(HTTP::getServerPort(), ':3030');
// Test HTTP + standard port
$_SERVER['SERVER_PORT'] = '80';
$this->assertEquals(HTTP::getServerPort(), '');
// Test HTTP + standard integer port
$_SERVER['SERVER_PORT'] = 80;
$this->assertEquals(HTTP::getServerPort(), '');
// Test HTTP + without port
unset($_SERVER['SERVER_PORT']);
$this->assertEquals(HTTP::getServerPort(), '');
// Test HTTPS + non-standard port
$_SERVER['HTTPS'] = 'on';
$_SERVER['SERVER_PORT'] = '3030';
$this->assertEquals(HTTP::getServerPort(), ':3030');
// Test HTTPS + non-standard integer port
$_SERVER['SERVER_PORT'] = 3030;
$this->assertEquals(HTTP::getServerPort(), ':3030');
// Test HTTPS + standard port
$_SERVER['SERVER_PORT'] = '443';
$this->assertEquals(HTTP::getServerPort(), '');
// Test HTTPS + without port
unset($_SERVER['SERVER_PORT']);
$this->assertEquals(HTTP::getServerPort(), '');
$_SERVER = $original;
}
/**
* Test SimpleSAML\Utils\HTTP::checkURLAllowed(), with the regex as a
* subdomain of an evil domain.
*/
public function testCheckURLAllowedWithRegexWithoutDelimiters()
{
$original = $_SERVER;
Configuration::loadFromArray(array(
'trusted.url.domains' => array('app\.example\.com'),
'trusted.url.regex' => true,
), '[ARRAY]', 'simplesaml');
$_SERVER['REQUEST_URI'] = '/module.php';
$this->setExpectedException('\SimpleSAML\Error\Exception');
HTTP::checkURLAllowed('https://app.example.com.evil.com');
$_SERVER = $original;
}
}