diff --git a/phpBB/includes/startup.php b/phpBB/includes/startup.php
index 2f3b1c5324..d9dab2a356 100644
--- a/phpBB/includes/startup.php
+++ b/phpBB/includes/startup.php
@@ -95,6 +95,40 @@ function deregister_globals()
 	unset($input);
 }
 
+/**
+ * Check if requested page uses a trailing path
+ *
+ * @param string $phpEx PHP extension
+ *
+ * @return bool True if trailing path is used, false if not
+ */
+function phpbb_has_trailing_path($phpEx)
+{
+	// Check if path_info is being used
+	if (!empty($_SERVER['PATH_INFO']) || !empty($_SERVER['ORIG_PATH_INFO']))
+	{
+		return true;
+	}
+
+	// Match any trailing path appended to a php script in the REQUEST_URI.
+	// It is assumed that only actual PHP scripts use names like foo.php. Due
+	// to this, any phpBB board inside a directory that has the php extension
+	// appended to its name will stop working, i.e. if the board is at
+	// example.com/phpBB/test.php/ or example.com/test.php/
+	if (preg_match('#^[^?]+\.' . preg_quote($phpEx, '#') . '/#', $_SERVER['REQUEST_URI']))
+	{
+		return true;
+	}
+
+	return false;
+}
+
+// Check if trailing path is used
+if (phpbb_has_trailing_path($phpEx))
+{
+	exit('Trailing paths and path_info is not supported by phpBB 3.0');
+}
+
 // Register globals and magic quotes have been dropped in PHP 5.4
 if (version_compare(PHP_VERSION, '5.4.0-dev', '>='))
 {
diff --git a/tests/security/trailing_path_test.php b/tests/security/trailing_path_test.php
new file mode 100644
index 0000000000..72ec6b8816
--- /dev/null
+++ b/tests/security/trailing_path_test.php
@@ -0,0 +1,55 @@
+<?php
+/**
+ *
+ * @package testing
+ * @copyright (c) 2011 phpBB Group
+ * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License v2
+ *
+ */
+
+require_once dirname(__FILE__) . '/../../phpBB/includes/startup.php';
+
+class phpbb_security_trailing_path_test extends phpbb_test_case
+{
+	public function data_has_trailing_path()
+	{
+		return array(
+			array(false, '', '', ''),
+			array(true, '/', '', ''),
+			array(true, '/foo', '', ''),
+			array(true, '', '/foo', ''),
+			array(true, '/foo', '/foo', ''),
+			array(false, '', '', '/'),
+			array(false, '', '', '/?/x.php/'),
+			array(false, '', '', '/index.php'),
+			array(false, '', '', '/dir.phpisfunny/foo.php'),
+			array(true, '', '', '/index.php/foo.php'),
+			array(false, '', '', '/phpBB/viewtopic.php?f=3&amp;t=5'),
+			array(false, '', '', '/phpBB/viewtopic.php?f=3&amp;t=5/'),
+			array(false, '', '', '/phpBB/viewtopic.php?f=3&amp;t=5/foo'),
+			array(true, '/foo', '/foo', '/phpBB/viewtopic.php?f=3&amp;t=5/foo'),
+			array(false, '', '', '/projects/php.bb/phpBB/viewtopic.php?f=3&amp;t=5/'),
+			array(false, '', '', '/projects/php.bb/phpBB/viewtopic.php?f=3&amp;t=5'),
+			array(false, '', '', '/projects/php.bb/phpBB/viewtopic.php?f=3&amp;t=5/foo.php/'),
+			array(false, '', '', '/projects/php.bb/phpBB/index.php'),
+			array(true, '', '', '/projects/php.bb/phpBB/index.php/'),
+			array(true, '', '', '/phpBB/index.php/?foo/a'),
+			array(true, '', '', '/projects/php.bb/phpBB/index.php/?a=5'),
+			array(false, '', '', '/projects/php.bb/phpBB/index.php?/a=5'),
+		);
+	}
+
+	/**
+	 * @dataProvider data_has_trailing_path
+	 */
+	public function test_has_trailing_path($expected, $path_info, $orig_path_info, $request_uri)
+	{
+		global $phpEx;
+
+		$_SERVER['PATH_INFO'] = $path_info;
+		$_SERVER['ORIG_PATH_INFO'] = $orig_path_info;
+		$_SERVER['REQUEST_URI'] = $request_uri;
+
+		$this->assertSame($expected, phpbb_has_trailing_path($phpEx));
+	}
+}