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?
精彩评论