Что делает функция test_input, которой обрабатываются все входящие данные?
Часто встречаю в РНР коде функцию, которой обрабатываются все входящие данные. Например такую
function postCliner($data) {
$data = trim($data);
$data = strip_tags($data);
$data = stripslashes($data);
return $data;
}
Что это за код и за что он отвечает? Можете построчно его прокомментировать?
Ответы (1 шт):
Это бессмысленный набор функций у которого ноги растут из глубокой древности.
У языка РНР есть много недостатков, но самый большой из них - его простота. Позволяющая любому школьнику освоить базовый синтаксис за два дня и сразу начать писать сайты. Как следствие, большинство пишущих на РНР не понимают основных принципов как программирования, так и веб-разработки в частности. И такая неграмотность всегда становится источником многочисленных суеверий и заблуждений.
Вот эта функция как раз и является примером такого заблуждения, которое, к сожалению, нашло дорогу в кучу некачественных источников, начиная с печально известного сайта w3schools и заканчивая книгами, в частности авторства Робина Никсона или парочки Веллинг/Томпсон (Понятное дело, читать эти книги ни в коем случае не рекомендуется, даже если их можно бесплатно скачать из интернета. Читайте Дакетта или на худой конец Котерова)
Заблуждением в данном случае является идея о том, что входящие данные можно как-то один раз "обезвредить" на входе, и дальше уже не переживать за безопасность. Идея эта на редкость дурацкая. Просто потому, что все опасности очень разные, и защита всегда должны быть адресной, в каждом конкретном случае своя. А не делаться один раз от всего скопом.
Обычно в такой очистительной процедуре в разных сочетаниях встречаются следующие функции
- trim() в теории убирает лишние пробелы. Но иногда может испортить входящие данные
- stripslashes() это просто бессмысленная функция, которая только портит данные
- htmlspecialchars() не имеет отношения к очистке входящих данных. Она должна применяться при выводе данных, а не при получении.
- mysql(i)_escape_string которая по мнению многих поколений хомячков служит для защиты от коварных инъекций, хотя не имеет к ним ни малейшего отношения.
- strip_tags() - это странная функция, которая скорее испортит данные, чем сделает что-то полезное. По идее, она должна вырезать из текста HTML теги. И можно подумать, что она может помочь защитить сайт от взлома или дурацких шуток. Но во-первых, её недостаточно для защиты от взлома, а во-вторых, на нормально защищенном сайте она и не нужна. Нормальный сайт всегда экранирует данные при выводе, в соответствии с требуемым форматом. Если же не хотим допускать HTML теги, то данные надо валидировать: то есть проверить наличие тегов в тексте и если нашли - то не молча вырезать, а выдать пользователю ошибку, чтобы он сам решил, что с ними делать.
Ничего себе зоопарк, да?
Представьте себе человека, который круглые сутки носит не снимая бронежилет, спасательный круг, огнетушитель и презерватив. Ведь все эти вещи защищают же! Ну и что что большую часть времени они не нужны. Пусть будут! Вот именно такая логика и приводит к созданию подобных функций.
Но в реальности ведь никто так не делает. А все используют по мере надобности. Идет на пожар - берет огнетушитель. Идет в атаку - надевает бронежилет. Ну и так далее.
И в программировании должен соблюдаться тот же самый принцип: каждая мера защиты должна применяться на своем месте, причем не заранее, а в момент использования. Если передаем данные в SQL запрос, то делаем это через плейсхолдеры. Если выводим в html, то экранируем с помощью htmlspecialchars. Если выводим в яваскрипт, то экранируем с помощью json_encode. Если выводим в шелл, то экранируем с помощью escapeshellarg. И так далее.
В итоге можно сформулировать два простых правила для защиты:
- Защита должна быть адресной, а не общей
- Защищать данные надо не заранее, а ровно в момент использования.
Если же хочется как-то обрабатывать входящие данные, то такая обработка называется валидацией. И заключается в проверке данных и выдаче ошибки клиенту, если данные не подходят.