2009-09-16 3 views
0

Я не уверен, как кто-то сломает мой SQL, если я просто заменю все входящие одинарные кавычки двойными кавычками. Может ли кто-нибудь просветить меня как для Oracle, так и для SQL Server? Благодарю.SQL Injection, простейшее решение

string sql1 = "select * from users where user_id = '" + "O'Reily".Replace("'", "''").Replace("\", "") + "'"; 

==> "* Выберите из пользователей, где user_id = 'O''Reily'

string sql2 = "select * from users where user_id = '" + "O'''Reily".Replace("'", "''").Replace("\", "") + "'"; 

==>" * Выберите из пользователей, где user_id = 'O' '' ''» Reily "

ОБНОВЛЕНИЕ: косая черта '\' является ограниченным символом в приложении и будет удалена до того, как она будет использована в запросе. Двойную тире можно легко добавить в этот список символов ограниченного доступа.

+1

одинарные кавычки - это не столько проблема, как «-» и «;». По возможности ограничивайте ввод текста пользователем. –

+7

Обязательные Маленькие Таблицы Бобби: http://xkcd.com/327/ –

+0

У Бобби было бы хорошо с этим решением. Одинарная кавычка будет сбежать до двойника, и капля никогда не будет выполнена. – user112799

ответ

16

Спараметрировать переменные. Шутки в сторону. У всех современных сред есть возможности для этого, и вам не нужно беспокоиться о escape-последовательностях, например, «которые превратятся в» с вашей схемой (в Oracle), которая становится скрытой цитатой и обычной (завершающей) цитатой.

Есть много других трюков, чтобы вытащить это, что я не перечисляю, поскольку они не помогают.

Снова: параметризуйте свои переменные. Шутки в сторону. Если вы не научитесь использовать параметризацию, то будет стать еще одной взломанной статистикой.

EDIT: Прочитайте ссылки в ответ Павла и здесь нет другой: http://unixwiz.net/techtips/sql-injection.html

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

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

+1

+1 Определенно согласитесь, что это одна из тех ситуаций, когда вы получаете это умное (неправильное) чувство при создании своего решения. – llamaoo7

+0

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

+0

Спасибо, я знаю, что это правильный путь. Я всегда думал на каком-то уровне, паразитируя данные, в любом случае делал какую-то манипуляцию с регулярным выражением/строкой, хотя все равно. – user112799

3

Ваше предлагаемое решение уязвим для включения строки \', которая завершит ваш цитируемый раздел и позволит впрыскивать другие команды.

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

Несколько ссылок:

http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html

http://java.sun.com/docs/books/tutorial/jdbc/basics/prepared.html

http://mattbango.com/notebook/web-development/prepared-statements-in-php-and-mysqli/

4

Чтобы предотвратить SQL-инъекцию, вам действительно нужно использовать привязанные позиционные или именованные параметры вместо того, чтобы строить ваш SQL как строку с пользовательским вводом inlined. Как это делается, зависит от того, как ваше приложение обращается к базе данных.Например, вот что это будет выглядеть в Java с использованием JDBC:

Bad:

String updateString = "UPDATE COFFEES SET SALES = 75 " + 
         "WHERE COF_NAME LIKE 'Colombian'"; 
stmt.executeUpdate(updateString); 

Хорошо:

PreparedStatement updateSales = con.prepareStatement(
     "UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ? "); 
updateSales.setInt(1, 75); 
updateSales.setString(2, "Colombian"); 
updateSales.executeUpdate(): 

Я позаимствовал пример отсюда: http://java.sun.com/docs/books/tutorial/jdbc/basics/prepared.html

+0

Это действительно мешает мне печатать updateSales.setString (2, "; DELETE YOUR_DATA; -" –

+0

rexem: yes. Oracle, например, проведет фазу анализа, чтобы проверить синтаксис SQL. В этот момент, он не смотрит на содержимое переменных привязки. SQL не может быть выполнен без успешного анализа. В «хорошем» примере параметры определяются как переменная связывания, никогда не анализируются как часть оператора SQL и не могут исполняемый. В качестве «побочного эффекта» операторы могут быть повторно использованы для разных значений переменных привязки, поэтому в базе данных меньше парсинга и меньше нагрузки. –

+0

+1 Если поддерживается, используйте переменные bind. Я думаю, что в php поддержка отсутствует. , C#, c/C++, ... большинство языков. Поскольку sql анализируется (или интерпретируется) отдельно от значений, это единственная защита от SQL-инъекции. – Christian13467

0

Есть некоторые трюки с участием злоумышленника, использующего ввод усечения ввода:

http://www.rampant-books.com/t_super_sql_154_ideas_prevent_injection.htm

+0

спасибо, что это была хорошая ссылка, но она полагается на строковые данные b eing обрезается до фиксированной ширины, а затем удаляет исправление, которое было реализовано. Кроме того, длина ввода в коде asp не соответствует длине, выводимой в базу данных. – user112799

Смежные вопросы