Это действительно очень опасно делать что-то вроде: opendir($local_directory)
, где $local_directory
- это значение, которое может прийти извне.
Что, если кто-то пройдет что-то вроде ../../../../../../../../../etc
... или что-то в этом роде? Вы рискуете поставить под угрозу безопасность вашего хоста.
Вы можете взглянуть сюда, чтобы начать:
http://php.net/manual/en/book.filter.php
ИМХО, если вы ничего не создаете на лету, у вас должно быть что-то вроде:
$allowed_dirs = array('dir1','dir2', 'dir3');
if (!in_array($myvar, $allowed_dirs)) {
// throw an error and log what has happened
}
Вы можете сделать это сразу после того, как получите свой вклад извне. Если для вас это нецелесообразно, поскольку число папок изображений может меняться со временем, и вы боитесь пропустить синхронизацию с вашей кодовой базой, вы также можете заполнить массив допустимых значений, выполнив сканирование имеющихся у вас подкаталогов в образе папки в первую очередь.
Итак, в конце вы можете получить что-то вроде:
$allowed_dirs = array();
if ($handle = opendir(dirname(__FILE__) . '/images')) {
while (false !== ($entry = readdir($handle))) {
$allowed_dirs[] = $entry;
}
closedir($handle);
}
$myvar=$_GET['var'];
// you can deny access to dirs you want to protect like this
unset($allowed_dirs['private_stuff']);
// rest of code
$local_directory = dirname(__FILE__) . "/images/.$myvar";
if (in_array(".$myvar", $allowed_dirs) && $handle = opendir($local_directory)) {
$i=0;
while (false !== ($entry = readdir($handle))) {
if(strstr($entry, 'sample_'.$language.'-'.$type)) {
$result[$i]=$entry;
$i++;
}
}
closedir($handle);
} else {
echo 'error';
}
Код выше НЕ оптимизирован. Но давайте избегать преждевременной оптимизации в этом случае (указав это, чтобы избежать еще одного «приятного» снижения); сниппет просто для того, чтобы дать вам представление о явном разрешении значений VS альтернативному подходу, разрешающему все, кроме соответствия определенному шаблону. Я думаю, что первый более безопасен.