Многие веб-разработчики даже не догадываются, что SQL-запросы могут быть подделаны, и считают, что SQL-запросы всегда достоверны. На самом деле поддельные запросы могут обойти ограничения доступа, стандартную проверку авторизации, а некоторые виды запросов могут дать возможность выполнять команды операционной системы.
Принудительное внедрение вредоносных инструкций в SQL-запросы - методика, в которой взломщик создает или изменяет текущие SQL-запросы для работы со скрытыми данными, их изменения или даже выполнения опасных команд операционной системы на сервере базы данных. Атака выполняется на базе приложения, строящего SQL-запросы из пользовательского ввода и статических переменных. Следующие примеры, к сожалению, построены на реальных фактах.
Благодаря отсутствию проверки пользовательского ввода и соединением с базой данных под учетной записью суперпользователя (или любого другого пользователя, наделенного соответствующими привелегиями), взломщик может создать еще одного пользователя БД с правами суперпользователя.
urlencode():// используя PostgreSQL 0; insert into pg_shadow(usename,usesysid,usesuper,usecatupd,passwd) select 'crack', usesysid, 't','t','crack' from pg_shadow where usename='postgres'; -- // используя MySQL 0; UPDATE user SET Password=PASSWORD('crack') WHERE user='root'; FLUSH PRIVILEGES; |
Замечание: Уже привычна технология, когда разработчики указывают принудительное игнорирование парсером SQL оставшейся части запроса при помощи нотации --, означающей комментарий.
Еще один вероятный способ получить пароли учетных записей в БД - атака страниц, предоставляющих поиск по базе. Взломщику нужно лишь проверить, используется ли в запросе передаваемая на сервер и необрабатываемая надлежащим образом переменная. Это может быть один из устанавливаемых на предыдущей странице фильтров, таких как WHERE, ORDER BY, LIMIT и OFFSET, используемых при построении запросов SELECT. В случае, если используемая вами база данных поддерживает конструкцию UNION, взломщик может присоединить к оригинальному запросу еще один дополнительный, для извлечения пользовательских паролей. Настоятельно рекомендуем использовать только зашифрованные пароли.
Команды UPDATE также могут использоваться для атаки. Опять же, есть угроза разделения инструкции на несколько запросов, присоединения дополнительного запроса. Также взломщик может видоизменить выражение SET. В этом случае потенциальному взломщику необходимо обладать некоторой дополнительной информацией для успешного манипулирования запросами. Эту информацию можно получить, проанализировав используемые в форме имена переменных либо просто перебирая все наиболее распространенные варианты названия соответствующих полей (а их не так уж и много).
<?php |
Пугающий пример того, как на сервере баз данных могут выполняться команды операционной системы.
$query = "SELECT * FROM products |
Замечание: Некоторые приведенные в этой главе примеры касаются конкретной базы данных. Это не означает, что аналогичные атаки на другие программные продукты невозможны. Работоспособность вашей базы данных может быть нарушена каким-либо другим способом.
Вы можете утешать себя тем, что в большинстве случаев, взломщик должен обладать некоторой информацией о структуре базы данных. Вы правы, но вы не знаете, когда и как будет предпринята попытка взлома, в случае если это произойдет ваша БД окажется незащищенной. Если вы используете программный продукт с открытыми исходными кодами или просто общедоступный пакет для работы с базой данных (например контент менеджер или форум), взломщик легко сможет воспроизвести интересующие его участки кода. В случае если они плохо спроектированы, это может являться одной из угроз вашей безопасности.
Большинство успешных атак основывается на коде, написанном без учета соответствующих требований безопасности. Не доверяйте никаким вводим данным, особенно если они поступают со стороны клиента, даже если это списки в форме, скрытые поля или куки. Приведенные примеры показывают, к каким последствиям могут привести подделанные запросы.
Старайтесь не открывать соединение с базой, используя учетную запись владельца или администратора. Всегда старайтесь использовать специально созданных пользователей с максимально ограниченными правами.
Всегда проверяйте введенные данные на соответствие ожидаемому типу. В PHP есть множество функций для проверки данных: начиная от простейших Функций для работы с переменными и Функции определения типа символов (такие как is_numeric(), ctype_digit()) и заканчивая Perl-совместимыми регулярными выражениями.
В случае, если приложение ожидает цифровой ввод, примените функцию is_numeric() для проверки введенных данных, или принудительно укажите их тип при помощи settype(), или просто используйте числовое представление при помощи функции sprintf().
Пример 27-6. Более безопасная реализация постраничной навигации
|
Экранируйте любой нецифровой ввод, используемый в запросах к БД при помощи функций addslashes() или addcslashes(). Обратите внимание на первый пример. Следует помнить, что одного использования кавычек в запросе мало, это легко обойти.
Не выводите никакой информации о БД, особенно о ее структуре. Также ознакомьтесь с соответствующими разделами документации: Сообщения об ошибках и Функции обработки и логирования ошибок.
Вы можете использовать хранимые процедуры и заранее определенные курсоры для абстрагированной работы с данными, не предоставляя пользователям прямого доступа к данным и представлениям, но это решение имеет свои особенности.
Помимо всего вышесказанного, вы можете логировать запросы в вашем скрипте либо на уровне базы данных, если она это поддерживает. Очевидно, что логирование не может предотвратить нанесение ущерба, но может помочь при трассировке взломанного приложения. Лог-файл полезен не сам по себе, а информацией, которая в нем содержится. Причем, в большинстве случаев полезно логировать все возможные детали.
Пред. | Начало | След. |
Защита хранилища базы данных | Уровень выше | Сообщения об ошибках |