Плохой код: Почему это опасно?
Возможный дубликат:
Могу ли я защитить от SQL Injection, выполнив одиночную кавычку и окружающий пользовательский ввод с помощью одиночных кавычек?
String badInput = rawInput.replace("'","''");
ResultSet rs = statement.executeQuery("SELECT * FROM records WHERE col1 = '"+badInput+"'";
Есть ли способ сделать " Bobby Tables" - как атака на этот код?
Ответы
Ответ 1
В зависимости от разных шагов по тому, как все должны интерпретировать команду, может быть некоторая возможность передать %27
(например) и заставить ее действовать как одинарная цитата, пропуская незаметно через вашу замену.
Но даже если бы все такие случаи могли быть охвачены, и это было действительно безопасно для этого единственного вопроса, ему не хватает того, что он не может быть единообразно реализован. Кто-то еще может прийти и захочет добавить AND int1 = var1
, и замечает, что вы подумали о SQL-инъекции, поэтому они просто изменяют код точно таким образом, что у вас есть
String badInput = rawInput.replace("'","''");
String badInteger = rawInteger.replace("'","''");
ResultSet rs = statement.executeQuery("SELECT * FROM records WHERE" +
"int1 = " + badInteger + " OR col1 = '"+badInput+"'");
... только с целыми числами, которые больше не цитируются, вы хотите защитить себя! Здесь очевидно, что все может пойти не так. Таким образом, хотя эта проблема требует от кого-то ее плохо реализовать, я думаю, что это самая большая проблема дизайна - она охватывает только узкий набор случаев.
Всегда лучше иметь возможность просто сказать: "Ниже приведена переменная, независимо от того, что она содержит, рассматривайте ее как значение и не пытайтесь использовать ее в качестве кода и выполнять этот код".
Ответ 2
В MySQL, если параметр NO_BACKSLASH_ESCAPES не установлен, я считаю, что это возможно.
\'); DROP
Или что-то подобное. Ваш код удвоит значение '
. Первый '
будет экранирован обратным слэшем, а второй закроет строку, разрешающую SQL-инъекцию.
Обычно я предпочитаю придерживаться подготовленных инструкций, чтобы быть в безопасности.
Ответ 3
Недавно я представил моего брата в подготовительное выражение. Внедрив его в своем текущем проекте, он обнаружил
- Он мог избавиться от всех беспорядочных побегов
- он мог бы избавиться от всей беспорядочной конкатенации строк
- Его код работал быстрее.
Почему никто не будет готовить?
Ответ 4
Вы можете попробовать:
badInput = "\\'; drop records; --";
если ваш escape-символ установлен на '\'
.
Ответ 5
Может быть. Зависит от того, что на самом деле делает этот метод replace
, особенно когда он встречает суррогатные пары юникода или комбинирует метки - и аналогичным образом, как эти пары обрабатываются технологией доступа к базе данных. Если replace
работает на уровне char, тогда если злоумышленник снабдит вас действительным высоким суррогатом, за которым следует символ с одной кавычкой, вы можете заменить эту одиночную кавычку парой одиночных кавычек - по сути, добавить одиночная цитата после чего-то-мая - позже проходит через кодировку и интерпретируется как недействительная суррогатная пара, оставляя голой символ одиночной кавычки.
Может быть.
Знаете ли вы о характеристиках Unicode этого метода замены и каждой промежуточной библиотеки обработки строк между вашим кодом и механизмом выполнения SQL на другом конце соединения с БД?
Вам повезло?
Использовать параметризованный запрос.
Ответ 6
Я не эксперт по безопасности, но не могу char()
эффективно обойти ваши меры безопасности?
Например: Получение всего из таблицы записей
SELECT * FROM records WHERE col1 = char(39,97,39)
Например: 2: Запись информации в файлы без одинарных кавычек
SELECT * FROM records WHERE col1 = concat(char(39),char(97),char(100),char(109),char(105),char(110),char( 39)) into outfile concat(char(39),char(97),char(100),char(109),char(105),char(110),char( 39))
Источник здесь: SQL Injection Cheat Sheet
Ответ 7
Потому что должен быть только один хакер, который изобретает способ обойти "замены" на пути, о котором мы не можем думать сегодня. (Небольшая ошибка в одном из слоев для доступа к базе данных???)
Ответ 8
Это склонно и всегда приглашает на инъекцию.