PHP аутентификация + mod_rewrite - PullRequest
       1

PHP аутентификация + mod_rewrite

0 голосов
/ 12 сентября 2010

У меня есть 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 голосов
/ 15 сентября 2010

Разве не проще установить автоматическое добавление для дерева каталогов?

0 голосов
/ 12 сентября 2010

Сначала удалите часть '/ special' из вашего правила mod_rewrite, в этом нет необходимости, вам просто нужно имя файла.

Тогда попробуйте это:

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

basename () будет отрезать любой путь от $ filename.

0 голосов
/ 12 сентября 2010

Это сработало:

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

Если реальный путь к имени файла не начинается с этой строки, он прерывается.

0 голосов
/ 12 сентября 2010
$filename = basename($_GET['filename']);

оставит только имя файла вне любой данной строки

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...