Защита от атаки 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 в частности.