предисловие
Инъекция SQL является высоким фактором риска. Теперь он в настоящее время все чаще в рамках нашего прочного слоя. Следовательно, большинство из структур посвящены этой проблеме, поэтому у нас все меньше интересно. Недавний отдел упомянул некоторые модификации для инъекций SQL, когда они организуют уязвимости безопасности, поэтому они узнали.
текст
принцип
Принцип sql-инъекций заключается в том, чтобы замаскировать sql-код во входные параметры и передать его на сервер для анализа и выполнения. То есть некоторый код sql имплантируется в некоторые параметры запроса, инициированные на стороне сервера.Когда сторона сервера выполняет операцию sql, она будет соединять соответствующие параметры, а также соединять некоторый «sql» атаки SQL-инъекции, в результате при выполнении некоторых неожиданных операций.
Пример:
Например, интерфейс входа в систему, который мы используем: интерфейс входа включает поля ввода имени пользователя и пароля, а также кнопку отправки, введите имя пользователя и пароль и отправьте.
При входе в систему вызовите интерфейс /user/login/ и добавьте параметры имя пользователя и пароль, сначала подключитесь к базе данных, а затем выполните проверку параметров имени пользователя и пароля, переносимых в параметрах запроса в фоновом режиме, то есть sql процесс запроса. Предполагая, что правильными именем пользователя и паролем являются ls и 123456, ввод правильного имени пользователя и пароля и отправка эквивалентны вызову следующей инструкции SQL.
SELECT * FROM user WHERE username = 'ls' AND password = '123456'
В sql строки после # и -- обрабатываются как комментарии.Если мы используем "' или 1=1 #" в качестве параметра имени пользователя, то оператор sql, созданный сервером, будет выглядеть следующим образом:
select * from users where username='' or 1=1#' and password='123456'
И # будет игнорировать следующий оператор, поэтому приведенный выше sql также эквивалентен:
select * from users where username='' or 1=1
И 1=1 является постоянным условием, поэтому этот sql становится следующим, и все зарегистрированные пользователи опрашиваются.
select * from users
Фактически, приведенная выше sql-инъекция просто выполняет некоторые трюки на уровне параметров.Если будет введен какой-либо функциональный sql, это будет более опасно, например, в приведенном выше интерфейсе входа, если имя пользователя использует это "' или 1=1; удалить * от пользователей; #", то это равносильно еще одному новому sql после ";". Этот sql удаляет всю таблицу, что является очень опасной операцией. Поэтому следует уделить особое внимание sql инъекции.
Решить принцип sql инъекции
предварительная компиляция sql
Узнав принцип sql инъекции, мы также узнали, что в mysql есть функция прекомпиляции, а это значит, что при старте сервера клиент mysql отправляет шаблон sql оператора (переменные размещаются с заполнителями) на сервер mysql , сервер mysql компилирует шаблон оператора sql.После компиляции соответствующий индекс оптимизируется в соответствии с оптимизационным анализом оператора.Когда параметры окончательно привязаны, соответствующие параметры отправляются на сервер mysql для непосредственного выполнения, что экономит время SQL-запроса, а также ресурсы сервера mysql, он может достичь цели одной компиляции и нескольких выполнений, а также может предотвратить внедрение SQL.
Как предотвратить SQL-инъекцию? Фактически, когда связанные параметры передаются серверу mysql, сервер mysql компилирует параметры, то есть заполняет их соответствующими заполнителями и выполняет операцию побега. Наш часто используемый jdbc имеет функцию предварительной компиляции, которая не только повышает производительность, но и предотвращает внедрение SQL.
String sql = "select id, no from user where id=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setInt(1, id);
ps.executeQuery();
Строгая проверка параметров
Про проверку параметров и говорить нечего, достаточно заранее выполнить проверку спецсимволов в некоторых параметрах, которые не должны иметь спецсимволов.
--Структура поддержки Mybatis
Экология Java очень часто используется в кадрах постоянного уровня. Mybatis может завершить предотвращение SQL-инъекций, как показано ниже, два файла Mapper, первый может предотвратить, а второй нет.
<select id="selectByNameAndPassword" parameterType="java.util.Map" resultMap="BaseResultMap">
select id, username, password, role
from user
where username = #{username,jdbcType=VARCHAR}
and password = #{password,jdbcType=VARCHAR}
</select>
<select id="selectByNameAndPassword" parameterType="java.util.Map" resultMap="BaseResultMap">
select id, username, password, role
from user
where username = ${username,jdbcType=VARCHAR}
and password = ${password,jdbcType=VARCHAR}
</select>
- # Обрабатывайте входящие данные как строку и добавляйте двойные кавычки к автоматически входящим данным. Например: где имя пользователя = # {имя пользователя}, если входящее значение равно 111, значение при анализе в sql будет таким, где имя пользователя = "111", если входящим значением является id, проанализированный sql будет таким, где имя пользователя = "id".
-
{username}, если входящее значение равно 111, значение при анализе в sql будет таким, где имя пользователя = 111; если входящее значение ;drop table user;, проанализированный sql: выберите идентификатор, имя пользователя, пароль, роль от пользователя, где username=;удалить пользователя таблицы;
Поэтому, если вы действительно не хотите выполнять функциональный sql, такой как удаление таблиц, создание таблиц и т. д., вам все равно нужно использовать #, чтобы избежать внедрения sql. Нижний слой mybatis по-прежнему использует предварительно скомпилированную функцию jdbc.
Эпилог
Выше приведено небольшое резюме методов, принципов и опасностей SQL-инъекций, а также решения проблем.Если возникнут какие-либо проблемы, я надеюсь, что вы сможете указать на них и сообщить больше.