Безопасные символы для разрешения доступа к файлу в каталоге - PullRequest
0 голосов
/ 10 января 2011

У меня есть PHP-скрипт, который позволяет пользователям удалять определенные файлы в каталоге, указав имя файла (с помощью раскрывающегося списка - но это достаточно просто для изменения злоумышленником).Я «очищаю» имя файла, выполняя следующие действия:

if(preg_match(/'/^[a-zA-Z0-9.]$/'/,$file)) {
    # do stuff to this particular file
}

Я вполне уверен, что это должно помешать кому-либо заняться чем-нибудь неприятным, но поскольку у людей здесь больше знаний,Я, я думал, я бы спросил - есть ли здесь дыра, или это будет держать противника подальше?

Ответы [ 4 ]

2 голосов
/ 10 января 2011

Я не уверен, поможет ли ваше регулярное выражение действительно: вне этого диапазона есть допустимые символы, которые вы не сможете удалить таким способом.

Одна вещь, которую я бы сделал, это сделать realpath() на полном окончательном пути и проверьте, является ли он дочерним по отношению к разрешенному пути к файлу.Это предотвратит атаки с обходом каталога ../../, даже если они используют некоторые специальные символы.Это уже должно обеспечить довольно хорошую безопасность.

Вы также можете дополнительно просканировать каталог, используя glob(), и проверить результаты, чтобы увидеть, действительно ли там находится запрошенный файл (который невозможно обойти даже при самом скрытом).Обратный путь в каталогах.)

Если вы хотите быть абсолютно параноиком , вы можете использовать совсем другой подход: не передавать имена файлов, а перечислять индексы списка, который вы указалидо.Например, если вы показываете этот список пользователю и сохраняете его во временном текстовом файле или записи базы данных:

  1. Readme.txt
  2. Лицензия
  3. Readme.doc

и затем передайте только (случайный) идентификатор текстового файла или записи базы данных и номер файла, который вы хотите удалить:

delete.php?list=xasdafdas&index=3

у вас должно бытьрешение, которое довольно неуязвимо против любого мыслимого вида инъекций и взлома имен файлов.

Вы должны хранить индивидуальный список для каждого запроса, так как файлы могут измениться.

0 голосов
/ 10 января 2011

Если ваше имя файла не является абсолютным путем, и вы всегда префикс пути к каталогу

chdir(...); // change directory to that directory

// make use the $file is not contains '/'
$file = basename($file);

// check $file is not in list of files that you don't allow for delete
if ($file=='index.php' ...)
{
  // do nothing
  return false;
}


if (is_file($file))
{
  unlink($file); // or other actions
}
0 голосов
/ 10 января 2011

Это регулярное выражение будет соответствовать практически любому.Вы имели в виду /^[a-zA-Z0-9.]/ вместо этого?Это все равно будет соответствовать что-то вроде ../../../etc/shadow./^[a-zA-Z0-9.]+$/ (или просто /^[\w\d.]+$/) лучше, или вы можете просто проверить имя файла по массиву, из которого вы создали выпадающий список.

0 голосов
/ 10 января 2011

возможно, вам следует изменить свое регулярное выражение в

if(preg_match(/'/^[^a-zA-Z0-9.]+$/'/,$file)) {
# do stuff to this particular file
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...