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

Как работает атака SQL-инъекции

Для примера, можно представить зал суда, в котором человек по имени Боб предстает перед судом и вот-вот предстанет перед судьей. При заполнении документов до суда Боб пишет свое имя как «Боб может быть свободен». Когда судья доходит до дела и читает его вслух: «теперь вызываем Боб может быть свободен», судебный пристав отпускает Боба, потому что судья так сказал.

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

Простое сравнение между обычными и вредоносными инструкциями SQL

Обычный SQL-запрос

В этом обычном SQL-запросе строка studentId передается в инструкцию SQL. Цель состоит в том, чтобы просмотреть список студентов для студента, который соответствует введенному studentId. После обнаружения, что запись студента будет возвращена. Проще говоря, команда говорит: «Найдите этого пользователя и дайте мне его данные».

Код может выглядеть примерно так:

studentId = getRequestString ("studentId");

lookupStudent = "SELECT * FROM students WHERE studentId = " + studentId

Если студент вводит идентификатор студента 117 внутри веб-страницы формы с надписью: «Пожалуйста, введите свой идентификационный номер студента» полученный SQL-запрос будет выглядеть так:

SELECT * FROM students WHERE studentId = 117;

Эта команда вернет запись для конкретного студента с studentId, который содержит данные, которые разработчик внес.

Запрос SQL-инъекции

В этом примере злоумышленник вводит в поле ввода команду SQL или логическое выражение, а затем вводит идентификационный номер учащегося.

SELECT * FROM students WHERE studentId = 117 OR 1=1;

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

SQLi работает, ориентируясь на уязвимый интерфейс прикладного программирования или API. API в данном случае — это программный интерфейс, через который сервер получает запросы и отвечает на них.

Как предотвратить атаку SQL-инъекции

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

Существует ряд методов снижения риска нарушения данных в результате внедрения SQL-кода. В качестве наилучшей практики следует использовать несколько стратегий. Рассмотрим несколько наиболее распространенных реализаций:

  • Использование подготовленных операторов (с параметризованными запросами). Этот метод очистки входных данных базы данных включает в себя принуждение разработчиков сначала определить весь SQL-код, а затем передать только определенные параметры в SQL-запрос. Вводимые данные явно имеют ограниченную область, которую он не может расширить за ее пределы. Это позволяет базе данных проводить различие между вводимыми данными и выполняемым кодом независимо от типа данных, указанных в поле ввода. Некоторые библиотеки объектно-реляционного сопоставления (ORM) обычно используются для этой цели, так как некоторые версии будут автоматически очищать входные данные базы данных. Защитить все введеные пользовательские данные. При написании SQL определенные символы или слова имеют особое значение. Например, символ «*» означает «все», а слова «или» являются условиями. Чтобы обойти пользователей, которые вводят эти символы случайно или злонамеренно в запрос API к базе данных, вводимые пользователем данные могут быть экранированы. Экранирование символа — это способ сказать базе данных не анализировать его как команду или условие, а вместо этого рассматривать его как литеральный ввод.
  • Использование хранимых процедур. Хотя сама по себе стратегия безопасности не является надежной, хранимые процедуры могут помочь ограничить риск, связанный с внедрением SQL. При правильном ограничении разрешений учетной записи базы данных, выполняющей запросы SQL, даже ненадежный код приложения, уязвимый для внедрения SQL, не будет иметь разрешений, необходимых для управления несвязанными таблицами базы данных. Хранимые процедуры могут также проверять тип входных параметров, предотвращая ввод данных, которые нарушают тип поля, предназначенного для получения. В случаях, когда статических запросов недостаточно, хранимых процедур обычно следует избегать.

Соблюдение минимальных прав. Как правило, во всех случаях, когда сайт должен использовать динамический SQL, важно уменьшить воздействие на SQL инъекции, путем ограничения прав доступа к узкой области, необходимых для выполнения соответствующего запроса. В наиболее очевидной форме это означает, что учетная запись администратора ни в коем случае не должна выполнять команды SQL в результате вызова API из несанкционированного запроса. Хотя хранимые процедуры лучше всего использовать для статических запросов, применение минимальных привилегий может помочь снизить риски динамических запросов SQL.