Защита от атаки SQL-инъекции "WAITFOR DELAY"?

проблема

нам нужно защитить от атаки SQL-инъекции "WAITFOR DELAY" в нашем приложении java.

фон

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

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

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

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

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

нападение

аудит уязвимостей сообщил об ошибке внедрения 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 секунд. Злоумышленник может связать все подключения к базе данных в пуле БД и эффективно закройте свой сайт.

некоторые наблюдения об этой атаке "WAITFOR DELAY"

  • Я думал, что, поскольку мы использовали оператор 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 ответов


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

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

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


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

нет абсолютно никакого оправдания для не использования подготовленных операторов для такого простого запроса в этот день и век.

(Edit: хорошо, не "абсолютно" - но есть почти никогда не оправдание)


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

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


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

является ли это жизнеспособным решением для атаки WAITFOR?

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

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

нет. Смотреть выше.

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

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

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


все остальные прибили это (parameterize!) но только чтобы коснуться нескольких моментов здесь:

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

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

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

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


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