aboutsummaryrefslogtreecommitdiffstats
path: root/phpBB/includes
diff options
context:
space:
mode:
authorHenry Sudhof <kellanved@phpbb.com>2008-05-15 13:29:14 +0000
committerHenry Sudhof <kellanved@phpbb.com>2008-05-15 13:29:14 +0000
commit9413af5e1a59a9bfc01fb5d3896a2fb5d34055f4 (patch)
treec3e3d93706bbf09bbc1451f14102ed85ae2af895 /phpBB/includes
parentae3dd106049e0b7429719862c82250ad2d28ffd7 (diff)
downloadforums-9413af5e1a59a9bfc01fb5d3896a2fb5d34055f4.tar
forums-9413af5e1a59a9bfc01fb5d3896a2fb5d34055f4.tar.gz
forums-9413af5e1a59a9bfc01fb5d3896a2fb5d34055f4.tar.bz2
forums-9413af5e1a59a9bfc01fb5d3896a2fb5d34055f4.tar.xz
forums-9413af5e1a59a9bfc01fb5d3896a2fb5d34055f4.zip
So, tighten things up a little further. QA Team, please check this.
git-svn-id: file:///svn/phpbb/branches/phpBB-3_0_0@8554 89ea8834-ac86-4346-8a33-228a782c2dd0
Diffstat (limited to 'phpBB/includes')
-rw-r--r--phpBB/includes/acp/acp_board.php11
-rw-r--r--phpBB/includes/constants.php5
-rw-r--r--phpBB/includes/session.php50
3 files changed, 64 insertions, 2 deletions
diff --git a/phpBB/includes/acp/acp_board.php b/phpBB/includes/acp/acp_board.php
index 4d82926ca2..4a42f1fd8b 100644
--- a/phpBB/includes/acp/acp_board.php
+++ b/phpBB/includes/acp/acp_board.php
@@ -323,6 +323,7 @@ class acp_board
'ip_check' => array('lang' => 'IP_VALID', 'validate' => 'int', 'type' => 'custom', 'method' => 'select_ip_check', 'explain' => true),
'browser_check' => array('lang' => 'BROWSER_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'forwarded_for_check' => array('lang' => 'FORWARDED_FOR_VALID', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
+ 'referer_validation' => array('lang' => 'REFERER_VALID', 'validate' => 'int:0:3','type' => 'custom', 'method' => 'select_ref_check', 'explain' => true),
'check_dnsbl' => array('lang' => 'CHECK_DNSBL', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'email_check_mx' => array('lang' => 'EMAIL_CHECK_MX', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'pass_complex' => array('lang' => 'PASSWORD_TYPE', 'validate' => 'string', 'type' => 'select', 'method' => 'select_password_chars', 'explain' => true),
@@ -676,7 +677,17 @@ class acp_board
return h_radio('config[ip_check]', $radio_ary, $value, $key);
}
+
+ /**
+ * Select referer validation
+ */
+ function select_ref_check($value, $key = '')
+ {
+ $radio_ary = array(REFERER_VALIDATE_PATH => 'REF_PATH', REFERER_VALIDATE_HOST => 'REF_HOST', REFERER_VALIDATE_NONE => 'NO_REF_VALIDATION');
+ return h_radio('config[referer_validation]', $radio_ary, $value, $key);
+ }
+
/**
* Select account activation method
*/
diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php
index eb4eb77f22..7c681a4040 100644
--- a/phpBB/includes/constants.php
+++ b/phpBB/includes/constants.php
@@ -171,6 +171,11 @@ define('FIELD_BOOL', 4);
define('FIELD_DROPDOWN', 5);
define('FIELD_DATE', 6);
+// referer validation
+define('REFERER_VALIDATE_NONE', 0);
+define('REFERER_VALIDATE_HOST', 1);
+define('REFERER_VALIDATE_PATH', 2);
+
// Additional constants
define('VOTE_CONVERTED', 127);
diff --git a/phpBB/includes/session.php b/phpBB/includes/session.php
index 8239921ba8..33fce6731b 100644
--- a/phpBB/includes/session.php
+++ b/phpBB/includes/session.php
@@ -158,6 +158,7 @@ class session
$this->cookie_data = array('u' => 0, 'k' => '');
$this->update_session_page = $update_session_page;
$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'));
$this->page = $this->extract_current_page($phpbb_root_path);
@@ -263,8 +264,17 @@ class session
$s_forwarded_for = ($config['forwarded_for_check']) ? substr($this->data['session_forwarded_for'], 0, 254) : '';
$u_forwarded_for = ($config['forwarded_for_check']) ? substr($this->forwarded_for, 0, 254) : '';
+
+ // referer checks
+ $check_referer_path = $config['referer_validation'] == REFERER_VALIDATE_PATH;
+ $referer_valid = true;
+ if ($config['referer_validation'] && isset($_SERVER['REQUEST_METHOD']) && strtolower($_SERVER['REQUEST_METHOD']) !== 'get')
+ {
+ $referer_valid = $this->validate_referer($check_referer_path);
+ }
+
- if ($u_ip === $s_ip && $s_browser === $u_browser && $s_forwarded_for === $u_forwarded_for)
+ if ($u_ip === $s_ip && $s_browser === $u_browser && $s_forwarded_for === $u_forwarded_for && $referer_valid)
{
$session_expired = false;
@@ -343,7 +353,14 @@ class session
// Added logging temporarly to help debug bugs...
if (defined('DEBUG_EXTRA') && $this->data['user_id'] != ANONYMOUS)
{
- add_log('critical', 'LOG_IP_BROWSER_FORWARDED_CHECK', $u_ip, $s_ip, $u_browser, $s_browser, htmlspecialchars($u_forwarded_for), htmlspecialchars($s_forwarded_for));
+ if ($referer_valid)
+ {
+ add_log('critical', 'LOG_IP_BROWSER_FORWARDED_CHECK', $u_ip, $s_ip, $u_browser, $s_browser, htmlspecialchars($u_forwarded_for), htmlspecialchars($s_forwarded_for));
+ }
+ else
+ {
+ add_log('critical', 'LOG_REFERER_INVALID', $this->referer);
+ }
}
}
}
@@ -1279,6 +1296,35 @@ class session
$this->set_login_key($user_id);
}
}
+
+
+ /**
+ * Check if the request originated from the same page.
+ * @param bool $check_script_path If true, the path will be checked as well
+ */
+ 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) )
+ {
+ return true;
+ }
+ $host = htmlspecialchars($this->host);
+ $ref = substr($this->referer, strpos($this->referer, '://') + 3);
+ if (!(stripos($ref , $host) === 0))
+ {
+ return false;
+ }
+ else if ($check_script_path && !empty(rtrim($this->page['root_script_path'], '/')))
+ {
+ $ref = substr($ref, strlen($host));
+ if (!(stripos(rtrim($ref, '/'), rtrim($this->page['root_script_path'], '/')) === 0))
+ {
+ return false;
+ }
+ }
+ return true;
+ }
}