Что делает функция 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. И так далее.

В итоге можно сформулировать два простых правила для защиты:

  1. Защита должна быть адресной, а не общей
  2. Защищать данные надо не заранее, а ровно в момент использования.

Если же хочется как-то обрабатывать входящие данные, то такая обработка называется валидацией. И заключается в проверке данных и выдаче ошибки клиенту, если данные не подходят.

→ Ссылка