Защищаться от SQL-инъекции «WAITFOR DELAY»? - PullRequest
7 голосов
/ 08 января 2010

Проблема

Нам нужно защищаться от sql-атаки «WAITFOR DELAY» в нашем java-приложении.

Фон

[Это долго. Перейти к «Решение?» раздел ниже, если вы спешите]

Наше приложение в основном использует подготовленные операторы и вызываемые операторы (хранимые процедуры) при доступе к базе данных.

В некоторых местах мы динамически строим и выполняем запросы для выбора. В этой парадигме мы используем объект критерия для построения запроса в зависимости от критериев пользовательского ввода. Например, если пользователь указал значения для first_name и last_name, запрос результата всегда будет выглядеть примерно так:

SELECT first_name,last_name FROM MEMBER WHERE first_name ='joe' AND last_name='frazier'

(В этом примере пользователь указал бы «joe» и «frazier» в качестве своих входных значений. Если бы у пользователя было больше или меньше критериев, у нас были бы более длинные или более короткие запросы. Мы обнаружили, что этот подход проще чем использование подготовленных операторов и более быстрая / более производительная, чем хранимые процедуры).

Атака

Аудит уязвимости сообщил об ошибке внедрения SQL. Злоумышленник ввел значение 'frazier WAITFOR DELAY '00: 00: 20' для параметра 'last_name', в результате чего получилось следующее sql:

   SELECT first_name,last_name FROM MEMBER WHERE first_name ='joe' AND last_name='frazier' WAITFOR DELAY '00:00:20'

Результат: запрос выполняется успешно, но для его выполнения требуется 20 секунд. Злоумышленник может связать все ваши подключения к базе данных в пуле базы данных и эффективно закрыть ваш сайт.

Некоторые наблюдения об этой атаке "ЗАДЕРЖКА ОЖИДАНИЯ"

  • Я думал, что, поскольку мы использовали Statement executeQuery (String), мы были бы защищены от внедрения SQL. executeQuery (String) не будет выполнять DML или DDL (удаляет или удаляет). И executeQuery (String) блокирует точки с запятой, поэтому парадигма 'таблиц Бобби' потерпит неудачу (т. Е. Пользователь вводит "frazier; DROP TABLE member" для параметра. См. http://xkcd.com/327/)

  • Атака «WAITFOR» отличается одним важным аспектом: WAITFOR изменяет существующую команду «SELECT» и не является отдельной командой.

  • Атака работает только на «последний параметр» в результирующем запросе. то есть 'WAITFOR' должен встречаться в самом конце оператора sql

Решение, дешевый взлом или оба?

Наиболее очевидное решение заключается в простом добавлении «И 1 = 1» в предложение where.

Полученный sql сразу завершается неудачей и мешает атакующему:

   SELECT first_name,last_name FROM MEMBER WHERE first_name ='joe' AND last_name='frazier' WAITFOR DELAY '00:00:20' AND 1=1

Вопросы

  • Это жизнеспособное решение для атаки WAITFOR?
  • Защищает ли он от других подобных уязвимостей?
  • Я думаю, что лучший вариант влечет за собой использование подготовленных заявлений. Больше работы, но менее уязвимо.

Ответы [ 6 ]

22 голосов
/ 08 января 2010

Правильный способ обработки SQL-инъекций - использовать параметризованные запросы.Все остальное просто писает на ветру.Это может сработать один раз, даже дважды, но в конечном итоге вы будете поражены этим теплым чувством, которое говорит: «Вы облажались, плохо!»оптимально, и вам нужно убедиться, что в вашем решении нет других дыр, которые вам нужно исправить.

Параметризованные запросы, с другой стороны, работают "из коробки" и предотвращают все этиатаки.

11 голосов
/ 08 января 2010

SQL-инъекция - это SQL-инъекция - в WAITFOR DELAY.

нет ничего особенного

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

(Правка: Хорошо, не «абсолютно» - но почти никогда оправдание)

3 голосов
/ 08 января 2010

Я думаю, вы предложили решение самостоятельно: Параметризованные запросы .

Как вы обнаружили, что ваш динамически создаваемый запрос выполняется быстрее, чем использование хранимой процедуры? В общем, часто бывает наоборот.

2 голосов
/ 08 января 2010

Чтобы ответить на все ваши вопросы:

Это жизнеспособное решение для атаки WAITFOR?

Нет. Просто добавьте - к строке атаки, и она проигнорирует ваше исправление.

Защищает ли он от других подобных уязвимостей?

Нет. Смотри выше.

Я думаю, что лучший вариант влечет за собой использование подготовленных заявлений. Больше работы, но менее уязвимо.

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

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

0 голосов
/ 14 января 2010

Все остальные прибили это (параметризация!), Но здесь стоит затронуть пару моментов:

  • Это жизнеспособное решение для атаки WAITFOR?
  • Защищает ли он от других подобных уязвимостей?

Нет, это не так. Трюк WAITFOR, скорее всего, просто используется для «обнаружения» уязвимости; Как только они нашли уязвимую страницу, они могут сделать гораздо больше без DDL или (без SELECT) DML. Например, подумайте, если они передали следующее как last_name

' UNION ALL SELECT username, password FROM adminusers WHERE 'A'='A

Даже после того, как вы добавили AND 1 = 1, вы все еще находитесь в шланге. В большинстве баз данных есть много вредоносных действий, которые вы можете сделать, просто нажав SELECT ...

0 голосов
/ 08 января 2010

Как насчет следования xkcd и дезинфекции ввода. Вы можете проверить зарезервированные слова в целом и для WAITFOR в частности.

...