предисловие
В последнее время я разбираюсь с проблемами, связанными с уязвимостями безопасности, и я собираюсь поделиться этим с компанией. Так совпало, что за это время команда обнаружила уязвимость sql-инъекций: в функции публичного пейджинга в качестве входного параметра используется поле сортировки, а фронтенд-страницу можно настраивать. в пагинации sqlmybatis
mapper.xml
середина,order by
После поля используйте символ $ для динамического получения рассчитанных параметров сортировки, чтобы можно было реализовать функцию динамической сортировки.
Однако, если входной параметр передается в:
id; select 1 --
Окончательный выполненный sql станет:
select * from test1 order by id; select 1 -- limit 1,20
--
поставлю спинуlimit
Оператор закомментирован, что приводит к сбою условия подкачки и возврату всех данных. Злоумышленник может использовать эту уязвимость для получения всех данных сразу.
Первоначальная идея функции динамической сортировки хороша, но естьsql注入的风险
. К счастью, на этот раз мы вовремя обнаружили проблему и вовремя решили ее, не причинив никакого ущерба.
Однако, когда я был в своем старом клубе несколько лет назад, мне не так повезло.
Недавно я случайно получил заметку о чистке, написанную крупным производителем BAT, которая открыла мне сразу вторую линейку Ren и Du, и я все больше чувствую, что алгоритм не так сложен, как я себе представлял.Заметки о чистке, написанные боссом BAT, позвольте мне мягко получить предложение
SQL-инъекция напрямую повесила наш платежный сервис.
1. Восстановить место аварии
Однажды ко мне подошла операционистка и сказала, что есть много пользователей, которые не могут платить. Этот платежный сервис - старая система, ее меняли 3 человека, и она работала очень стабильно без каких-либо проблем.
Не мудрствуя лукаво, я начал искать проблему.Во-первых, я просмотрел журнал сервера и обнаружил множество исключений, сообщающих о слишком большом количестве подключений к базе данных. Поскольку платежная функция слишком важна, чтобы обеспечить быстрое восстановление платежной функции, мы сначала попросили службу эксплуатации и обслуживания перезапустить два узла платежной службы.
Это временно вернулось к норме через 5 минут.
Я продолжу искать причину.Согласно моему опыту в то время, обычно слишком много подключений к базе данных, что может быть из-за соединения.忘了关闭
Привести к. Но тщательная проверка кода не выявила никаких проблем: пул соединений с базой данных, который мы использовали в то время, автоматически перезапускал незанятые соединения.排除了这种可能
.
Через некоторое время другой узел имеет слишком много подключений к базе данных.
Но на данный момент причина до сих пор не найдена, и мне ничего не остается, как просить службу эксплуатации и обслуживания перезапустить службу, но на этот раз базу данных.最大连接数调大
Теперь значение по умолчанию равно 100, мы установили 500 в то время, а позже изменили его на 1000. (На самом деле, большинство компаний теперь устанавливают этот параметр равным1000
)
Используйте команду:
set GLOBAL max_connections=500;
Это может вступить в силу со временем без перезапуска службы mysql.
На этот раз это дало мне больше времени и попросило администратора базы данных помочь мне вместе исследовать причину.
он используетshow processlist;
Команда для просмотра текущего выполнения потока:
Вы также можете просмотреть текущее состояние подключения, чтобы определить проблемные операторы запроса.
- идентификатор потока
- Учетная запись пользователя для выполнения sql
- Хост IP-адрес и номер порта базы данных, на которой выполняется sql.
- имя базы данных бд
- Команда Выполнение команд, в том числе: Daemon, Query, Sleep и т. д.
- Время Время, потраченное на выполнение sql
- Состояние исполнения
- info Информация о выполнении, которая может содержать информацию sql.
Действительно, был найден необычный запрос sql, и он выполнялся почти час, прежде чем был завершен.
dba скопировал sql и отправил мне. потомkill -9
Убейте поток sql, выполнение которого занимает много времени.
Позже проблема слишком большого количества подключений к базе данных больше не появлялась.
Я получил sql и тщательно проанализировал его, и обнаружил, что оператор запроса порядка был введен злоумышленником в длинный sql.Он должен быть написан мастером, и я никогда не видел некоторых грамматик.
Но можно подтвердить, что он был введен SQL.
По информации в sql я быстро нашел соответствующий код, а входные параметры использовались при запросе данных.Statment
, вместоPrepareStatement
Механизм прекомпиляции.
Зная причину, с ней легко справиться, и изменить место запроса данных наpreparestatement
Проблема была окончательно решена после предварительной компиляции механизма.
2. Почему это вызывает слишком много подключений к базе данных?
Я полагаю, что у многих студентов возникнет вопрос, когда они увидят это: почему SQL-инъекция вызывает слишком много подключений к базе данных?
Я использую картинку ниже, чтобы объяснить это вам:
- Злоумышленник sql вводит такие параметры:
-1;锁表语句--
. - в
;
Предыдущий оператор запроса выполняется первым. - так как
--
Следующие операторы будут закомментированы, а затем будет выполнен только оператор блокировки таблицы, чтобы заблокировать таблицу. - После того, как обычный бизнес-запрос успешно получает соединение из пула соединений с базой данных, когда с таблицей необходимо манипулировать, он пытается получить блокировку таблицы, но не может получить ее до истечения времени ожидания. Обратите внимание, что большое количество подключений к базе данных может быть занято и не возвращено вовремя.
- Недостаточно пула соединений с базой данных, свободных соединений нет.
- Новый бизнес-запрос не может получить соединение из пула соединений с базой данных, и сообщается об аномалии слишком большого количества соединений с базой данных.
SQL-инъекция вызывает слишком много подключений к базе данных, и наиболее фундаментальной причиной является долгосрочная блокировка таблицы.
3. Почему предварительная компиляция может предотвратить внедрение sql?
preparestatement
Механизм предварительной компиляции будет анализировать, компилировать и оптимизировать оператор SQL перед его выполнением, где в позиции параметра используются заполнители.?
вместо.
При фактическом запуске переданные параметры будут рассматриваться как обычный текст, не будут перекомпилироваться и не будут рассматриваться как команды SQL.
Таким образом, даже если входной параметр передается в команду внедрения sql, например:
id; select 1 --
Окончательный выполненный sql станет:
select * from test1 order by 'id; select 1 --' limit 1,20
Таким образом, не будет проблем с внедрением sql.
4. Безопасна ли предварительная компиляция?
Я не знаю, использовали ли вы подобный оператор при запросе данных.Например, чтобы запросить пользователей со словом «Su» в их именах, вы можете использовать такой оператор:
select * from user where name like '%苏%';
Обычно проблем нет.
Однако в некоторых сценариях требуются входящие условия, например: требуется имя, если введено:%
, окончательный выполненный sql станет таким:
select * from user where name like '%%%';
В этом случае механизм прекомпиляции проходит нормально, но результат выполнения sql не вернет%
пользователей, но возвращаются все пользователи.
Обязательное поле имени становится бесполезным, а злоумышленник также может получить все данные пользовательской таблицы.
Почему возникает эта проблема?
%
это ключевое слово в mysql, если вы используетеlike '%%%'
, подобное условие будет недействительным.
Как это решить?
нужно%
Сбежать:\%
.
Сбежавший sql становится:
select * from user where name like '%\%%';
вернется только содержащий%
Пользователь.
5. А как насчет особых сцен?
В java, если вы используетеmybatis
В качестве основы сохранения вmapper.xml
файл, если используется параметр#
По значению будет использоваться механизм прекомпиляции.
Обычно мы используем это так:
<sql id="query">
select * from user
<where>
name = #{name}
</where>
</sql>
В большинстве случаев всем рекомендуется использовать#
Передача параметров таким образом безопаснее и эффективнее.
Но иногда бывают и частные случаи, например:
<sql id="orderBy">
order by ${sortString}
</sql>
Содержимое поля sortString динамически вычисляется в методе, что в данном случае бесполезно.#
,заменять$
Да, программа сообщит об ошибке.
использовать$
В этом случае есть риск SQL-инъекции.
Так что же делать в этой ситуации?
- Напишите утилиту для фильтрации всех введенных ключевых слов и вызывайте ее во время динамического расчета.
- Если в качестве источника данных используется друид Али, можно открыть стену (брандмауэр) в фильтре, включающем функцию предотвращения SQL-инъекций. Но есть проблема, то есть он по умолчанию не позволяет работать нескольким операторам одновременно, а также перехватывает операции пакетного обновления, что требует от нас настройки фильтра.
6. Как происходит утечка информации из таблицы?
Некоторые внимательные учащиеся могут задать вопрос: как в приведенном выше примере с блокировкой таблицы злоумышленник получил информацию о таблице?
Способ 1: слепое угадывание
То есть злоумышленник угадывает возможное имя таблицы, исходя из здравого смысла.
Предположим, у нас есть это условие запроса:
select * from t_order where id = ${id};
Входящие параметры:-1;select * from user
Окончательный sql выполнения становится:
select * from t_order where id = -1;select * from user;
Если sql возвращает данные, это означает, что пользовательская таблица существует и была угадана.
Рекомендуется не делать имя таблицы слишком простым, а можно привести соответствующий префикс, например: t_user. Это может увеличить сложность слепого угадывания.
Способ 2: через системные таблицы
На самом деле, в mysql есть некоторые системные таблицы, вы можете найти информацию о нашей пользовательской базе данных и таблице.
Предположим, мы все же возьмем этот sql в качестве примера:
select code,name from t_order where id = ${id};
Первым шагом является получение базы данных и имени учетной записи.
Параметры передаются как:-1 union select database(),user()#
Окончательный sql выполнения становится:
select code,name from t_order where id = -1 union select database(),user()#
вернет текущее имя базы данных:sue
и имя учетной записи:root@localhost
.
Второй шаг — получить имя таблицы.
Измените параметр на:-1 union select table_name,table_schema from information_schema.tables where table_schema='sue'#
Окончательный sql выполнения становится:
select code,name from t_order where id = -1 union select table_name,table_schema from information_schema.tables where table_schema='sue'#
вернет базу данныхsue
Все названия таблиц ниже.
7. Чем опасны SQL-инъекции?
1. Утечка основных данных
Целью большинства злоумышленников является зарабатывание денег, получение ценной информации для продажи денег, такой как: учетная запись пользователя, пароль, номер мобильного телефона, данные удостоверения личности, номер банковской карты, адрес и другая конфиденциальная информация.
Они могут вводить такие утверждения:
-1; select * from user;--
Вы можете легко получить всю информацию в пользовательской таблице.
Поэтому рекомендуется шифровать и хранить эту конфиденциальную информацию, которую вы можете использоватьAES
Симметричное шифрование.
2. Удалить библиотеку и убежать
Есть также некоторые злоумышленники, которые не играют в карты в соответствии со здравым смыслом и напрямую удаляют системные таблицы или базы данных после SQL-инъекции.
Они могут вводить такие утверждения:
-1; delete from user;--
Приведенный выше оператор удалит все данные в пользовательской таблице.
-1; drop database test;--
Приведенный выше оператор удалит все содержимое всей тестовой базы данных.
В обычных обстоятельствах нам необходимо контролировать разрешения онлайн-аккаунтов и разрешать только операторы языка манипулирования данными DML (язык манипулирования данными), включая: выбор, обновление, вставка, удаление и т. д.
Операторы языка определения базы данных DDL (язык определения данных) не допускаются, в том числе: создание, изменение, удаление и т. д.
Операторы языка управления базой данных DCL (язык управления данными) также не разрешены, в том числе: предоставление, отказ, отзыв и т. д.
Операторы DDL и DCL могут работать только с учетной записью администратора dba.
Кстати: Если таблица или база данных удалены, то на самом деле есть меры по исправлению положения, то есть восстановление из файлов резервных копий может привести лишь к потере небольшого количества данных в реальном времени, поэтому должен быть механизм резервного копирования.
3. Повесить систему
Некоторые злоумышленники могут даже напрямую повесить наш сервис, как это было на старой компании.
Они могут вводить такие утверждения:
-1;锁表语句;--
После блокировки таблицы на долгое время это может привести к исчерпанию соединения с базой данных.
В это время нам нужно отслеживать поток базы данных.Если определенное время выполнения SQL слишком велико, требуется предупреждение по электронной почте. Кроме того, разумная установка времени ожидания соединения с базой данных также может немного облегчить эту проблему.
Из приведенных выше трех аспектов видно, что вред от проблемы внедрения sql действительно велик, мы должны избегать возникновения таких проблем и не рисковать. Если вы столкнетесь с некоторыми злоумышленниками, которые голосуют не в соответствии со здравым смыслом, когда вас атакуют, вы можете многое потерять.
8. Как предотвратить внедрение sql?
1. Используйте механизм прекомпиляции
Старайтесь максимально использовать механизм предварительной компиляции и меньше использовать сплайсинг строк для передачи параметров, что является основной причиной проблемы с SQL-инъекциями.
2. Чтобы экранировать специальные символы
Некоторые специальные символы, такие как:%
в видеlike
Параметры в операторе должны быть экранированы.
3. Чтобы ловить исключения
Все исключения должны быть перехвачены.Помните, что интерфейс возвращает информацию об исключении напрямую, потому что некоторая информация об исключении содержит информацию sql, включая: имя библиотеки, имя таблицы, имя поля и т. д. С помощью этой информации злоумышленник может атаковать вашу базу данных по своему желанию с помощью SQL-инъекций. Текущий основной подход состоит в том, чтобы иметь выделенную службу шлюза, которая единообразно предоставляет внешние интерфейсы. Когда пользователь запрашивает интерфейс, он сначала проходит через него, а затем перенаправляет запрос в бизнес-сервис. Преимущество этого заключается в том, что тело возвращаемых данных может быть инкапсулировано единообразно, а в случае возникновения исключения может быть возвращена унифицированная информация об исключении, чтобы скрыть конфиденциальную информацию. Кроме того, он также может выполнять ограничение тока и контроль разрешений.
4. Используйте инструменты для обнаружения кода
Используя инструменты обнаружения кода, такие как sqlMap, он может обнаруживать уязвимости SQL-инъекций.
5. Мониторинг
Необходимо следить за выполнением БД sql.При возникновении нештатной ситуации своевременное электронное или смс напоминание.
6. Учетная запись базы данных должна контролировать разрешения
Создайте отдельную учетную запись для базы данных в производственной среде и выделите толькоDML
соответствующие разрешения и не может получить доступ к системным таблицам. Не используйте учетную запись администратора непосредственно в программе.
7. Обзор кода
Создание механизма обзора кода может определить некоторые скрытые проблемы и улучшить качество кода.
8. Обработка другими способами
Если вы не можете использовать предварительно скомпилированные параметры, либо включитеdruid
изfilter
Брандмауэр или напишите логику кода, чтобы отфильтровать все возможные ключевые слова для внедрения.
Недавно я случайно получил заметку о чистке, написанную крупным производителем BAT, которая открыла мне сразу вторую линейку Ren и Du, и я все больше чувствую, что алгоритм не так сложен, как я себе представлял.Заметки о чистке, написанные боссом BAT, позвольте мне мягко получить предложение
Последнее слово (пожалуйста, обратите внимание, не проституируйте меня по пустякам)
Если эта статья полезна или вдохновляет вас, пожалуйста, помогите обратить внимание, ваша поддержка является самой большой мотивацией для меня, чтобы продолжать писать.
Попросите в один клик три ссылки: лайк, вперед и смотреть.
Следите за официальной учетной записью: [Су Сан сказал о технологии], ответьте в официальной учетной записи: интервью, артефакт кода, руководство по разработке, управление временем имеют большие преимущества для фанатов, и ответьте: присоединяйтесь к группе, вы можете общаться и учиться со старшими многих производители БАТ.