1
0
mirror of https://github.com/phpbb/phpbb.git synced 2025-02-24 12:03:21 +01:00

more in-depth hostname validation. Not used in install files... there the code is fine.

There are ways to improve this, either a whitelist or "more guessing"

git-svn-id: file:///svn/phpbb/branches/phpBB-3_0_0@8846 89ea8834-ac86-4346-8a33-228a782c2dd0
This commit is contained in:
Meik Sievertsen 2008-09-15 18:41:27 +00:00
parent cb1b5a3283
commit bca5a953de

View File

@ -136,6 +136,60 @@ class session
return $page_array;
}
/**
* Get valid hostname/port. HTTP_HOST is used, SERVER_NAME if HTTP_HOST not present.
*/
function extract_current_hostname()
{
global $config;
// Get hostname
$host = (!empty($_SERVER['HTTP_HOST'])) ? $_SERVER['HTTP_HOST'] : ((!empty($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : getenv('SERVER_NAME'));
// Should be a string and lowered
$host = (string) strtolower($host);
// If host is equal the cookie domain or the server name (if config is set), then we assume it is valid
if ((isset($config['cookie_domain']) && $host === $config['cookie_domain']) || (isset($config['server_name']) && $host === $config['server_name']))
{
return $host;
}
// Is the host actually a IP? If so, we use the IP... (IPv4)
if (long2ip(ip2long($host)) === $host)
{
return $host;
}
// Now return the hostname (this also removes any port definition). The http:// is prepended to construct a valid URL, hosts never have a scheme assigned
$host = @parse_url('http://' . $host);
$host = (!empty($host['host'])) ? $host['host'] : '';
// Remove any portions not removed by parse_url (#)
$host = str_replace('#', '', $host);
// If, by any means, the host is now empty, we will use a "best approach" way to guess one
if (empty($host))
{
if (!empty($config['server_name']))
{
$host = $config['server_name'];
}
else if (!empty($config['cookie_domain']))
{
$host = (strpos($config['cookie_domain']) === 0) ? substr($config['cookie_domain'], 1) : $config['cookie_domain'];
}
else
{
// Set to OS hostname or localhost
$host = (function_exists('php_uname')) ? php_uname('n') : 'localhost';
}
}
// It may be still no valid host, but for sure only a hostname (we may further expand on the cookie domain... if set)
return $host;
}
/**
* Start session management
*
@ -160,14 +214,8 @@ class session
$this->browser = (!empty($_SERVER['HTTP_USER_AGENT'])) ? htmlspecialchars((string) $_SERVER['HTTP_USER_AGENT']) : '';
$this->referer = (!empty($_SERVER['HTTP_REFERER'])) ? htmlspecialchars((string) $_SERVER['HTTP_REFERER']) : '';
$this->forwarded_for = (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) ? (string) $_SERVER['HTTP_X_FORWARDED_FOR'] : '';
$this->host = (!empty($_SERVER['HTTP_HOST'])) ? (string) strtolower($_SERVER['HTTP_HOST']) : ((!empty($_SERVER['SERVER_NAME'])) ? $_SERVER['SERVER_NAME'] : getenv('SERVER_NAME'));
// Since HTTP_HOST may carry a port definition, we need to remove it here...
if (strpos($this->host, ':') !== false)
{
$this->host = substr($this->host, 0, strpos($this->host, ':'));
}
$this->host = $this->extract_current_hostname();
$this->page = $this->extract_current_page($phpbb_root_path);
// if the forwarded for header shall be checked we have to validate its contents
@ -1322,7 +1370,7 @@ class session
function validate_referer($check_script_path = false)
{
// no referer - nothing to validate, user's fault for turning it off (we only check on POST; so meta can't be the reason)
if (empty($this->referer) || empty($this->host) )
if (empty($this->referer) || empty($this->host))
{
return true;
}
@ -1330,7 +1378,7 @@ class session
$host = htmlspecialchars($this->host);
$ref = substr($this->referer, strpos($this->referer, '://') + 3);
if (!(stripos($ref , $host) === 0))
if (!(stripos($ref, $host) === 0))
{
return false;
}