0

Сервер принимает данные, в которые легко можно записать любой скрипт или попробовать пробится через защиту на сервере или БД кавычками. Я пытаюсь закрыть все уязвимости максимально чисто, но при этом есть два условия:

  • Кавычки и переносы строк нужно оставить. При этом переносы строк идут из textarea, так что там будет происходить замена \n на <br>.
  • При проверке на пустое содержимое поля - поле только с символами, то есть кавычки или точки не должны проходить проверку и ответ будет "поле пустое".

В начале скрипта у меня установлена функция, зачищающая массив $_POST от лишнего, выглядит примерно так:

function quote_clear($data) {
  $data = str_replace("\n", '<br>', $data);
  $data = strip_tags($data, '<br>');
  $data = htmlspecialchars($data, ENT_QUOTES);
  return $data;
}
function quote($var) {
  foreach ($var as $row) {
   if(is_array($row)) {
     foreach($row as $row2) {
       $row2 = quote_clear($row2);
     }
   } else {
     $row = quote_clear($row);
   }
  }
    return $var;
}

Но в комментариях сказали что в базу обычно передают реальные данные, со всеми тегами, кавычками и чем либо другим. Я вижу своеобразную пользу от этого теперь, но я не понимаю как тогда работает защита в этом случае.

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

На сайте лежит форма в которой есть:

  • input(text) - для E-mail, мобильного телефона, имени заказчика, ссылок и так далее.
  • input(checkbox) - очевидно просто выбор категорий которые заказчик хочет включить в запрос.
  • textarea - комментарии к каждой категории, выбранной в checkbox.

Полагаю что любой из этих input может быть исправлен на клиенте, значит ко всем нужно привести определенные меры безопасности. Изначально я думал что если удалить все специальные символы, теги и экранизировать все что осталось то будет максимально безопасно, а главное универсально, но теперь я не понимаю что такое збезопасность вообще.

Не могли бы вы подсказать пример защиты данных в моем случае? Я использую mysqli.

Благодарю за внимание.

Telion
  • 1,810
  • Обычно фильтрация пользовательского ввода не считается хорошей защитой - нет гарантий, что вы её не забудете и нет гарантий, что вам в какой-то момент не потребуется фильтровать что-то ещё. Фильтрацию, насколько я знаю, лучше производить в тех местах, где вам поступают произвольные данные, а вы их хотите куда-то вывести; и не добавлять в систему инвариатов, что где-то какие-то данные хранятся безопасно. Например, при записи в БД используйте подстановку параметров вместо ручного "собирания" запроса, при выводе в HTML оборачивайте все данные в htmlspecialchars. – yeputons May 31 '17 at 15:27
  • У вас неправильный подход к защите, фильтровать следует не ввод, а вывод, нужно экранировать данные в sql-запросах с помощью mysqli или PDO, а в html экранировать непосредственно перед выводом (а не при вводе, как у вас) или, что предпочтительнее, использовать шаблонизатор – andreymal May 31 '17 at 15:29
  • @andreymal Окей, я понял что что-то делаю неправильно, но я не понял почему и как нужно. Я предполагал что перед тем как передать данные в БД я их чищу от возможного опасного кода, от кавычек, PHP тегов и т.д. и после этого сразу вношу в БД уже чистые данные. На выходе я предполагал можно декодировать (htmlspecialchars_decode) html код что остался и вот мы ничего важного не потеряли. (вроде как) – Telion May 31 '17 at 15:35
  • Посмотрите вот этот вопрос: https://ru.stackoverflow.com/a/571274/203622 – Мелкий May 31 '17 at 15:40
  • @Мелкий Ну так что я должен был вынести с этого вопроса? У меня на вход может прити что угодно через textarea и инпуты. Форма не для авторизации, а заказа. В ней лежит очень много checkbox, textarea для комментариев к некоторым полям и text для имени или имейла. Во всех полях я хочу избавится полностью от HTML и другого кода, оставить ТОЛЬКО кавычки, и переносы строк, что бы это было читабельно, все остальное не имеет никакой ценностия. Функция из вопроса работает так: $_POST = quote($_POST); и чистит все что мне не нужно, после чего я планирую добавить это в БД. Так что же я делаю не так? – Telion May 31 '17 at 16:07
  • 1
    @Telion ещё раз, если очень кратко, в БД должны быть грязные данные, а чистыми они должны становиться лишь непосредственно перед выводом в html-код.. То есть если я напишу коммент <script>alert(1);</script>"; drop table questions; -- — то он так и должен храниться в БД и ничего не должно вырезаться. Как видите, stackoverflow мой комментарий сохранил и ничего в нём не вырезал, но при этом никакого написанного мной кода не выполнилось :) К этому и нужно стремиться. – andreymal May 31 '17 at 16:49
  • @andreymal окей, но это же бесполезно заполненное пространство в бд для совершенно бесполезной информации, нет? Впрочем даже если так, как тогда этот грязный код безопасно вставить что бы не попасть под sql иньекции и другого рода проблемы? (П.С. это же stackoverflow, этот сайт как бы предназначен для этого рода данных, а мой нет, может это тоже играет роль) – Telion May 31 '17 at 17:06
  • @Telion полезность зависит от задачи, но обычно пользователи за порчу их сообщений по головке не гладят ;) Как вставить, я уже писал выше — mysqli или PDO. – andreymal May 31 '17 at 17:07
  • @andreymal вы имеете в виду mysqli_real_escape_string или какие-то другие методы или тут вообще есть какой-то магический неизвестный мне способ? А так, пользователи своих сообщений больше не увидят, их будет отправлено администраторам на рассмотрение. Но я полагаю в сохранении всей информации есть некая польза, так что посмотрим.. – Telion May 31 '17 at 17:16
  • @Telion я имею в виду подстановку параметров, о которой упоминалось в первом комментарии. mysqli и PDO при подстановке сами всё экранируют как положено, и никаких escape_string вам делать не требуется – andreymal May 31 '17 at 17:17
  • Вот тут это называют подготовленными выражениями http://phpfaq.ru/pdo – andreymal May 31 '17 at 17:20
  • @andreymal я использую mysqli, не подскажете пример безопасной вставки данных через него? При чем сразу в ответы, это закроет вопрос. – Telion May 31 '17 at 17:55
  • Ну например https://habrahabr.ru/post/141127/ Ответ пусть кто-нибудь другой пишет, я вообще-то php ненавижу и не пользую)) – andreymal May 31 '17 at 18:03

0 Answers0