Немного больше устойчивого regex может быть найдено в Regexp:: Распространенный .
Это кажется, что Вы хотите знать, думает ли Perl, что переменная является числовой. Вот функция, которая захватывает то предупреждение:
sub is_number{
my $n = shift;
my $ret = 1;
$SIG{"__WARN__"} = sub {$ret = 0};
eval { my $x = $n + 1 };
return $ret
}
Другая опция состоит в том, чтобы выключить предупреждение локально:
{
no warnings "numeric"; # Ignore "isn't numeric" warning
... # Use a variable that might not be numeric
}
Примечание, что нечисловые переменные будут тихо преобразованы в 0, который является, вероятно, что Вы хотели так или иначе.
Следующий код работает, даже если последний каталог в пути еще не существует. Любая нечестная игра или дополнительные пропущенные каталоги возвращают false.
Ограничение этой функции состоит в том, что она работает только с путями, которые (в основном) уже существуют, и именами каталогов, использующими стандартные английские символы (/.hts/, /files.90.3r3/, / my_photos /) и т. Д.)
function is_sub_dir($path = NULL, $parent_folder = SITE_PATH) {
//Get directory path minus last folder
$dir = dirname($path);
$folder = substr($path, strlen($dir));
//Check the the base dir is valid
$dir = realpath($dir);
//Only allow valid filename characters
$folder = preg_replace('/[^a-z0-9\.\-_]/i', '', $folder);
//If this is a bad path or a bad end folder name
if( !$dir OR !$folder OR $folder === '.') {
return FALSE;
}
//Rebuild path
$path = $dir. DS. $folder;
//If this path is higher than the parent folder
if( strcasecmp($path, $parent_folder) > 0 ) {
return $path;
}
return FALSE;
}
Не ответ на ваш непосредственный вопрос но вы не должны никогда использовать черные списки в реальной среде безопасности.
Это потому, что вы можете изменить макет каталогов, но забыть обновить черный список, в результате чего ваша безопасность бессильна.
Белый список - это список места, куда им разрешено загружать. Если вы затем измените макет и забудете изменить белый список, ваша безопасность фактически увеличится , а не уменьшится. / на /
(избавляется от бесполезных перемещений «остаться в текущем каталоге»).
/ X /../
на /
], где X - любой символ, отличный от /
(избавляет от перемещений каталогов вниз-вверх). То, что осталось, обычно безопасно для использования , хотя могут быть крайние случаи в зависимости от того, доступно ли больше команд перемещения каталога (я видел ...
как эквивалент ../ ..
). Ваш пробег может отличаться.
...
как эквивалент ../. .
). Ваш пробег может отличаться. s left, как правило, безопасно использовать, хотя могут быть крайние случаи в зависимости от того, доступны ли другие команды перемещения каталога (я видел ...
как эквивалент ../. .
). Ваш пробег может отличаться. Лучший способ Я знаю, что нужно просто сделать все, кроме каталога загрузки, недоступным для записи пользователем, от имени которого работает веб-сервер. Например, в Debian Apache работает от имени пользователя www-data
. Итак, я удостоверяюсь, что все каталоги, которые Apache может обслуживать как доступные для чтения / выполнения, принадлежат какому-то пользователю, кроме www-data
, и доступны для записи только этому пользователю (или какой-либо группе администраторов). Затем, если веб-сервер должен разрешить запись в каталог, Я делаю его доступным для записи www-data
либо через группу, либо через владельца.
Если это возможно, также неплохо переместить доступные для записи каталоги за пределы основного дерева серверов. Если я контролирую сервер, я создаю каталог в / var / lib
специально для этой цели. Если я не контролирую сервер, я помещаю его рядом с обслуживаемыми каталогами. Например, используя ваш пример / var / www / site
, я бы добавил еще один уровень, скажем / var / www / site / html
(для HTML с прямым обслуживанием и верхних скрипты уровня), / var / www / site / scripts
(для include ()
ed скриптов PHP) и / var / www / site / data
(для загруженные данные). Конечно, если вам нужно обслуживать загруженные данные,
Это так просто?
const UPLOAD_DIR = '/var/www/site/uploads/';
Каждый раз, когда вам нужно ее использовать, вы просто используете константу, так как похоже, что есть только одно место, куда вы можете загрузить. Таким образом, ты не сможешь так легко облажаться.
if ($dir != UPLOAD_DIR) {
// No access; Error
}
Иногда, чтобы защитить себя от самого себя, тебе просто нужно быть бдительным. Просто убедитесь, что вы вызываете is_sub_dir () перед любым доступом к файлам.
EDIT:
Теперь, когда вопрос более ясен, я вижу, что мой ответ не имеет смысла. =) Мой единственный другой совет - повторить то, что сказали другие: дезинфицировать, дезинфицировать, дезинфицировать.