Как избежать ввода в PHP? - PullRequest
1 голос
/ 23 ноября 2011

У меня есть страница PHP, которая принимает ввод от поста формы, но вместо того, чтобы направлять этот ввод в базу данных, он используется для извлечения файла из файловой системы.Что является хорошим методом для экранирования строки, предназначенной для файловой системы, а не для базы данных?Является ли mysql_real_escape_string () подходящим?

Ответы [ 2 ]

6 голосов
/ 23 ноября 2011

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

Например, что-то вроде

readfile($_GET['filepath']);

отправит на ваш сервер НИЧЕГО, для которого атака знает путь.Даже что-то вроде

readfile('/path/to/your/site/download/' . $_GET['filepath']);

выполняет то же самое, если пользователь указывает достаточно «../../../», чтобы получить любой файл, который он хочет.

mysql_real_escape_string () НЕ подходит для этого, так как вы не выполняете операцию с базой данных.Используйте соответствующие инструменты для соответствующей работы.По-глупому, m_r_e_s () - банан, и вам нужен жираф.Что-то вроде

readfile('/path/to/your/site/download/' . basename($_GET['filepath']));

будет относительно сохранено, так как basename () извлечет только часть имени файла предоставленного пользователем файла, поэтому даже если они передают ../../../../../etc/passwd, basename вернет только passwd.

0 голосов
/ 23 ноября 2011

Вам всегда нужно экранировать только символы, которые иначе интерпретируются вашей целевой системой.Для баз данных вы обычно избегаете кавычек, поэтому используете mysql_real_escape_string или другие.Если ваша цель - html, вы обычно используете htmlspecialchars, чтобы избавиться от специальных символов html (а именно <, > и &).Если ваша цель - CSV, вам нужно только убедиться, что разрывы строк и разделитель CSV экранированы.

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

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

edit:

Если вы хотите использовать ввод в качестве пути к файлу или имени файла, вы можете просто сами решить, насколько вы любезны, и какие символы выхочу поддержать.Простым способом было бы заменить все , кроме латинских символов и цифр (и, возможно, некоторые специальные символы, такие как _ и -), на что-то еще.Например:

preg_replace( '/[^A-Za-z0-9_-]/', '_', $text );
...