开发者

PHP authentication + mod_rewrite

I have a PHP script that tests is the user is logged in, for every page he accesses in a certain subdirectory. If he's logged in, he gets the page, otherwise he gets redirected to a login page. Instead of including this into every fi开发者_开发问答le (not possible since some are binary), I set up .htaccess like this

RewriteEngine On

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

And the contents of check.php are

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

The problem is that check.php is vulnerable to local file inclusion because I can pass ../ in filename to move to the parent directory and even leave /var/www. How can I restrict it to only reading from the special directory, or is there any way I can un-rewrite if the PHP check passes to allow Apache to read the target file instead of the PHP script reading the file?

Edit I also have subdirectories in the special directory. check.php is in the parent directory of the special directory.


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

will leave only filename off any given string


First, drop the '/special' part from your mod_rewrite rule, there is no need for it, you just want a file name.

Then try this:

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

basename() will cut off any path from $filename.


This worked:

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

If the real path to the filename doesn't start with that string, it aborts.


Wouldn't it just be simpler to set an auto-prepend for the dir tree?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜