
SQL-инъекции (также известные как «Нарушение в целостности структуры SQL-запроса») являются одними из самых распространённых и наиболее опасных уязвимостей в вопросе безопасности. SQL-инъекции очень опасны, потому что они открывают двери хакерам в вашу систему через веб-интерфейс, и позволяют получить неограниченный доступ: например удалять таблицы, изменять базу данных, и даже получить доступ к внутренней корпоративной сети. SQL-инъекции это чисто программная ошибка, и не имеет ничего общего с хост-провайдером. Итак, вы занимались поисками безопасного JSP хостинга, PHP хостинга, или любого другого, вы должны знать, что за профилактику SQL-инъекций несут ответственность только разработчики, а не хост провайдер.
Почему же происходят SQL-инъекции
SQL-инъекции это очень распространённая проблема, но по иронии судьбы, их также легко предотвратить. SQL-инъекции так распространены, поскольку очень много мест, где может присутствовать уязвимость, и в случае успешной инъекции, хакер может получить хорошую награду (например полный доступ к данным в базе).
Риск SQL-инъекций возникает всякий раз, когда программист создает динамический запрос к базе, содержащий введённые пользователем данные. Это значит способов предотвращения SQL-инъекций два:
• Не использовать динамических запросов к базе.
• Не использовать пользовательских данных в запросах.
Все вроде бы просто, но это теории, на практике же отказаться от динамических запросов невозможно, как и исключить пользовательский ввод данных. Но это не значит, что избежать инъекций невозможно. Есть некоторые приемы и технические возможности языков программирования, которые помогут предотвратить SQL-инъекции.
Что можно сделать для предотвращения SQL-инъекций
Хотя решение во многом зависит от конкретного языка программирования, все же общие принципы предотвращения SQL-инъекций схожи. Вот несколько примеров как это можно сделать:
• Использовать динамические запросы только в случае крайней необходимости.
Динамический запрос почти всегда можно заменить подготовленными выражениями (prepared statements), параметризованными запросами, или хранимыми процедурами. Например, вместо динамического SQL, в Java вы можете использовать PreparedStatement() с привязанными параметрами, в .NET вы можете использовать параметризованные запросы, такие как SqlCommand() или OleDbCommand()с привязанными параметрами, а в PHP вы можете использовать PDO со строгой типизацией параметризованных запросов (используя bindParam()).
В дополнение подготовленным выражениям (prepared statements), вы можете использовать хранимые процедуры. В отличие от подготовленных выражений (prepared statements), хранимые процедуры хранятся в базе, но в обоих случаях вначале определяется SQL-запрос, и в него передаются параметры.
• Проверка введенных данных в запросах.
Проверка ввода данных менее эффективна, чем параметризованные запросы и хранимые процедуры, но если нет возможности использовать параметризованные запросы и хранимые процедуры, то уж лучше все же проверять введенные данные – это лучше, чем ничего. Точный синтаксис использования проверки введенных данных сильно зависит об базы данных, читайте доки на вашу конкретную базу данных.
• Не надеяться на волшебные Кавычки (Magic Quotes).
Включение параметра magic_quotes_gpc может предотвратить некоторые (но не все) SQL-инъекции. Magic quotes никак не последняя защита, и что еще хуже, иногда они выключены и вы не знаете об этом, или не имеете возможности его включить. Именно поэтому необходимо использовать код, который будет экранировать кавычки. Здесь кусок кода, предложенный Джоном Ли:
$username = $_POST['username'];
$password = $_POST['password'];
if (!get_magic_quotes_gpc()) {
$username = addslashes($username);
$password = addslashes($password);
}• Регулярная и своевременная установка исправлений.
Даже когда ваш код не имеет уязвимостей, е��ть сервер баз данных, операционная система сервера, или утилиты разработчиков, которые могут иметь уязвимости. Именно поэтому всегда устанавливайте исправления сразу после их появления, особенно если это исправление SQL-инъекций.
• Удаляйте весь функционал, который вы не используете.
Сервер баз данных это сложное создание и имеет намного больше функционала, чем вам требуется. А то, что касается безопасности, тут принцип «чем больше – тем лучше» не работает. Например, расширенная системная процедура xp_cmdshell в MS SQL дает доступ к операционной системе, а это просто мечта для хакера. Именно поэтому эту функцию нужно отключать, как и любые другие, позволяющие легко злоупотреблять функционалом.
• Использование автоматизированных средств нахождения SQL-инъекций.
Даже если разработчики следовали всем вышеописанным правилам, чтобы избежать динамических запросов с подстановкой непроверенных пользовательских данных, вы все равно должны подтвердить это тестами и проверками. Существуют автоматизированные средства тестирования, для выявления SQL-инъекций, и нет оправдания тем, кто не пользуется этими средствами для проверки процедур и запросов.
Один из простых инструментов (и один из более-менее надежных) для выявления SQL-инъекций это расширение для Firefox`а именуемое SQL Inject ME. После установки этого расширения, инструмент доступен по правому клику в контекстном меню, или из меню Tools → Options. Рабочая область SQL Inject ME показана на следующем скриншоте, и вы можете видеть как много видов тестов вы можете провести:


Вы можете выбирать, какой тест запускать, и с какими параметрами. По окончанию проверки вы увидите отчет о результатах тестирования.
Множество параметров которые вы можете устанавливать для расширения SQL Inject ME, которые показаны на следующих двух скриншотах:


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