1

Чтобы не было XSS-инъекций, нужно использовать strip_tags(), htmlspecialchars(), htmlentities() при выводе пользовательского ввода. Думаю что лучше использовать strip_tags() и\или htmlentities().

Если этот вывод читается из базы данных, то сначала данные должны быть записаны в базу данных и тут появляются вопросы:

Что и в какой последовательности применять к данным которые буду писаться в базу данных?

2.1 Об stmt-запросах я знаю и понимаю https://www.php.net/manual/ru/mysqli.quickstart.prepared-statements.php

2.2 Хочу узнать примерные варианты порядка обработки данных перед сохранением в таблицу.

2.2.1 Сначала stip_tags() и\или htmlentities() -> (если нужно сохранить какое-то html форматирование в безопасном режиме)

2.2.2 потом mysqli_real_escape_string() - ?

2.2.3 Замена % и _ ( $more_escaped = addcslashes($escaped, '%_'); )

2.2.4 "теги", типа [b][code][i] [url] использовать для обработки ПЕРЕД выводом данных.

  1. В сети была замечательная статья о sql-инъекциях при помощи\на основе многобайтных кодировок. Кто что знает об этом способе sql-инъекций?

Да вот еще что, одинарных кавычек два типа:

` и '

какая-то из них не экранируется, нужно проверять?

Если не экранируется, то нужно экранировать отдельно (так как с _ и %)?

Aliskin
  • 412
  • 1
    Возможный дубликат вопроса: Грамотная защита от SQL-Injection – Visman May 15 '16 at 17:27
  • у вас в вопросе одновременно рассматриваются и XSS и SQL-Injection. Это две совершенно разных проблемы. Определитесь, какую именно вы будете бороть. Первая чинится экранированием (энкодингом) текста при выводе (и вообще не имеет никакого отношения к базам данных). Вторая - использованием параметризированных запросов (ну или костылями в виде экранирования sql), и, соответственно, не имеет никакого отношения к HTML. –  May 16 '16 at 09:02
  • меня и то, и то интересует. Но я уже как-бэ разобрался. – Aliskin May 21 '16 at 23:23

1 Answers1

2

В базу данных по возможности записывается весь текст без изменений, хотя бы для того, чтобы можно было восстановить порядок событий, кто, что, с какой целью загрузил и какого эффекта хотел добиться. Поэтому перед записью текст по возможности не фильтруется (даже если в нем откровенно деструктивная информация), а лишь экранируется. Если вы вставляете строки или цифры непосредственно в строку SQL-запроса, строки нужно обязательно экранировать, а цифры приводить к числовому значению, чтобы избежать SQL-инъекций.

Правда в последнее время получили распространение расширения mysqli и PDO, которые позволяют вставлять параметризированные запросы, prepare или stmt-запросы. Например

$query = "SELECT * 
          FROM catalogs
          WHERE catalog_id = :catalog_id";
$cat = $pdo->prepare($query);
$cat->execute(['catalog_id' => 1]);

В такой тип запроса вы SQL-инъекцию не вставите. В принципе проблема SQL-инъекций решается такими запросами как класс - используйте и можете не знать об них ничего (только не вставляйте параметры интерполяцией в строку).

Иначе в запрос вида

SELECT name FROM users WHERE id = $id

Можно вставить $id вида

$id = '0 UNION SELECT password WHERE id = 432'; 

В результате сформируется запрос

SELECT name FROM users WHERE id = 0
UNION
SELECT password WHERE id = 432   

Который вместо имени пользователя выведет пароль пользователя с идентификатором 432. Это не единственный тип SQL-инъекции, но повторю проблема решается как класс путем использованием prepare-запросов. Т.е. в этом случае не нужно даже экранировать и как-то специально обрабатывать данные - расширение само об этом позаботится.

Обратные кавычки ` характерны в основном для SQL-диалекта MySQL, они обрамляют названия таблицы и столбцов, чтобы оптимизатор не запутался, если название столбца или поля совпадает с ключевым словом - с ними почти невозможно ничего сделать. По крайней мере SQL-инъекции с их участием не известны - можно их специально не экранировать - от этого только проблемы при редактировании, когда у вас они по несколько раз могут эскейпится. Опасности от них, по крайней мере для базы данных, нет никакой.

Точно также относительно % и _ в текстовых полях они совершенно безопасны. Это шаблоны поиска LIKE и находятся они не со стороны шаблона, а в тексте.

cheops
  • 19,454
  • 29
  • 48
  • 139
  • Параметризированные запросы полностью решают проблему скл-индж? Но я считаю что этого не достаточно. – Aliskin May 15 '16 at 17:45
  • 1
    @root_xPovierennyy Почему вы так считаете ? параметризованные запросы исключают правку заданного в исходниках SQL в принципе. – Mike May 15 '16 at 18:53
  • незн. не верится (с трудом верится) мне что так просто решается эта "опасность". Помимо скл-внедрения есть множество других способов напрограммить себе большой мороки (хотя бы тот самый xss). НО я иду впИрьодт :). Что-то создается... – Aliskin May 15 '16 at 22:33
  • В вопросах безопасности лучше на верну не полагаться, а все перепроверять явно. Причем хорошо бы написать автоматические тесты, чтобы быть уверенным, что при дальнейшей поддержки проекта вам не сломают защиту. – cheops May 16 '16 at 04:51