Страницы

Поиск по вопросам

вторник, 2 октября 2018 г.

Грамотная защита от SQL-Injection

Уже давно меня мучает вопрос: Как защитить свой сайт от SQL-Injection. В былые времена я использовал mysql_real string_escape для экранирования кавычек. Но прошло некое время, и я узнал про PDO, говорится, мол, эта тема неплохо поможет в защите сайта. Скажем, я не великий хакер и никак это не могу проверить, я знаю, что при mysql_real string_escape все кавычки и прочая ерунда экранировались - и вуаля, вы уже в домике.
Сейчас я работаю над своим проектом и решил проверить сайт на защиту проникновения. В результате, что я делал:
Я просто брал и вводил данные с кавычками, например, Infor`mat'ion. Как я уже говорил, я не великий хакер, но точно знаю, что вся эта дрянь должна экранироваться, но она так и заносилась в базу данных, что натолкнуло меня на мысль, что никакой защиты у меня, по сути, и нету. А данные я заносил вот таким вот образом:
$sql = "INSERT INTO chat (time, login, private, text) values(?, ?, ?, ?)"; $db->prepare($sql)->execute(array($time, $login, $private, $text));`
Этот метод я вычитал на хабре в "Почему стоит пользоваться PDO для работы с базой данных", подключение такое же, как и указано в статье.
Как можно защититься от этих инъекций?


Ответ

При использовании подготовленных выражений (prepared statement) параметры внешнего происхождения отправляются на сервер отдельно от самого запроса либо автоматически экранируются клиентской библиотекой. Создаём таблицу drop_table. Далее $name = "Evil'); DROP TABLE drop_table;--";
$sql = "INSERT INTO `test` (`name`) values('{$name}');"; $statement = $db->prepare($sql); $statement->execute(); Таблица drop_table успешно удалена. :) Теперь тот же запрос, но только через prepared statement: $sql = "INSERT INTO `test` (`name`) values(?);"; $statement = $db->prepare($sql); $statement->execute([$name]); В таблицу test добавилась запись Evil'); DROP TABLE drop_table;-- UPDATE Таким образом, мы обезопасили себя от SQL injection, но не защитили от XSS В последнем случае требуется: валидация. К примеру, если необходимо оповестить пользователя о недопустимости введёных им данных либо для логирования; санитизация. Приведение данных к соответствующему типу (int)$age. В PHP существует набор фильтров, созданных именно для таких случаев; использования облегченного языка разметки. Markdown - именно им Вы и пользуетесь на хэшкоде, либо можно задействовать старичка bbCode. В идеале заставить не только рядового пользователя, но и администрацию сайта пользоваться им. В целях оптимизации, (чтобы каждый раз не парсить), можно воспользоваться key-value storage (memcached, redis,...) для хранения html версии. Если по каким-то причинам требуется хранить в базе html от источника, который не вызывает доверие, то можно воспользоваться HTML Purifier Немного рекламы: :) для валидации: Rock Validate для санитизации: Rock Sanitize

Комментариев нет:

Отправить комментарий