aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--phpBB/includes/functions.php30
-rw-r--r--tests/security/redirect_test.php16
2 files changed, 21 insertions, 25 deletions
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 35fa785616..744e610f32 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -999,7 +999,9 @@ function phpbb_own_realpath($path)
// @internal The slash in is_dir() gets around an open_basedir restriction
if (!@file_exists($resolved) || (!@is_dir($resolved . '/') && !is_file($resolved)))
{
- return false;
+ // In order to allow proper URL rewriting we need to allow
+ // paths that are non-existent
+ //return false;
}
// Put the slashes back to the native operating systems slashes
@@ -2696,20 +2698,6 @@ function redirect($url, $return = false, $disable_cd_check = false)
// Relative uri
$pathinfo = pathinfo($url);
- if (!$disable_cd_check && !file_exists($pathinfo['dirname'] . '/'))
- {
- $url = str_replace('../', '', $url);
- $pathinfo = pathinfo($url);
-
- if (!file_exists($pathinfo['dirname'] . '/'))
- {
- // fallback to "last known user page"
- // at least this way we know the user does not leave the phpBB root
- $url = generate_board_url() . '/' . $user->page['page'];
- $failover_flag = true;
- }
- }
-
if (!$failover_flag)
{
// Is the uri pointing to the current directory?
@@ -2723,14 +2711,7 @@ function redirect($url, $return = false, $disable_cd_check = false)
$url = substr($url, 1);
}
- if ($user->page['page_dir'])
- {
- $url = generate_board_url() . '/' . $user->page['page_dir'] . '/' . $url;
- }
- else
- {
- $url = generate_board_url() . '/' . $url;
- }
+ $url = generate_board_url() . '/' . $url;
}
else
{
@@ -2741,8 +2722,9 @@ function redirect($url, $return = false, $disable_cd_check = false)
$root_dirs = array_diff_assoc($root_dirs, $intersection);
$page_dirs = array_diff_assoc($page_dirs, $intersection);
+ $root_dirs_size = sizeof($root_dirs) - 2;
- $dir = str_repeat('../', sizeof($root_dirs)) . implode('/', $page_dirs);
+ $dir = (($root_dirs_size > 0) ? str_repeat('../', $root_dirs_size) : '') . implode('/', $page_dirs);
// Strip / from the end
if ($dir && substr($dir, -1, 1) == '/')
diff --git a/tests/security/redirect_test.php b/tests/security/redirect_test.php
index 8e36780ca4..e934a4ab1b 100644
--- a/tests/security/redirect_test.php
+++ b/tests/security/redirect_test.php
@@ -21,8 +21,22 @@ class phpbb_security_redirect_test extends phpbb_security_test_base
array('bad://localhost/phpBB/index.php', 'INSECURE_REDIRECT', false),
array('http://www.otherdomain.com/somescript.php', false, 'http://localhost/phpBB'),
array("http://localhost/phpBB/memberlist.php\n\rConnection: close", 'INSECURE_REDIRECT', false),
- array('javascript:test', false, 'http://localhost/phpBB/../javascript:test'),
+ array('javascript:test', false, 'http://localhost/phpBB/javascript:test'),
array('http://localhost/phpBB/index.php;url=', 'INSECURE_REDIRECT', false),
+ array('http://localhost/phpBB/app.php/foobar', false, 'http://localhost/phpBB/app.php/foobar'),
+ array('./app.php/foobar', false, 'http://localhost/phpBB/app.php/foobar'),
+ array('app.php/foobar', false, 'http://localhost/phpBB/app.php/foobar'),
+ array('./../app.php/foobar', false, 'http://localhost/phpBB/app.php/foobar'),
+ array('./../app.php/foo/bar', false, 'http://localhost/phpBB/app.php/foo/bar'),
+ array('./../foo/bar', false, 'http://localhost/phpBB/foo/bar'),
+ array('app.php/', false, 'http://localhost/phpBB/app.php/'),
+ array('./app.php/', false, 'http://localhost/phpBB/app.php/'),
+ array('foobar', false, 'http://localhost/phpBB/foobar'),
+ array('./foobar', false, 'http://localhost/phpBB/foobar'),
+ array('foo/bar', false, 'http://localhost/phpBB/foo/bar'),
+ array('./foo/bar', false, 'http://localhost/phpBB/foo/bar'),
+ array('./../index.php', false, 'http://localhost/phpBB/index.php'),
+ array('../index.php', false, 'http://localhost/phpBB/index.php'),
);
}