PHP身份验证+ mod_rewrite

时间:2010-09-12 11:55:47

标签: php apache authentication mod-rewrite

我有一个PHP脚本,测试用户是否已登录,因为他访问了某个子目录中的每个页面。如果他已登录,则会获取该页面,否则他将被重定向到登录页面。而不是将其包含在每个文件中(因为有些是二进制文件,因此不可能),我设置了像这样的.htaccess

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !^$
RewriteRule (.*) /check.php?filename=special/$1

check.php的内容是

if (!isset($_SESSION['username']))
{
    header("location: /login.html");
    die();
}
$filename = $_GET['filename'];
include($filename);

问题是check.php容易受到本地文件包含的影响,因为我可以在文件名中传递../以移动到父目录,甚至可以保留/ var / www。如何将其限制为仅从特殊目录中读取,或者如果PHP检查通过以允许Apache读取目标文件而不是读取文件的PHP脚本,是否有任何方法可以取消重写?

编辑我还在特殊目录中有子目录。 check.php位于特殊目录的父目录中。

4 个答案:

答案 0 :(得分:0)

$filename = basename($_GET['filename']);

将只留下任何给定字符串的文件名

答案 1 :(得分:0)

首先,从你的mod_rewrite规则中删除'/ special'部分,不需要它,你只需要一个文件名。

然后试试这个:

$your_dir = '/full/path/to/special';
$filename = basename($_GET['filename']);
if (file_exists($your_dir . '/' . $filename)) {
    include($filename);
}

basename()将切断$ filename的任何路径。

答案 2 :(得分:0)

这有效:

$filename = realpath($_GET['filename']);
if (strpos($filename, '/full/path/to/special') !== 0)
{
die();
}

如果文件名的实际路径不是以该字符串开头,则会中止。

答案 3 :(得分:0)

为dir树设置自动前置不是更简单吗?