SQL-инъекция, простейшее решение - PullRequest
0 голосов
/ 16 сентября 2009

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

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"

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

Ответы [ 4 ]

16 голосов
/ 16 сентября 2009

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

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

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

РЕДАКТИРОВАТЬ: прочитайте ссылки в ответе Павла, и вот еще: http://unixwiz.net/techtips/sql-injection.html

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

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

4 голосов
/ 16 сентября 2009

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

Плохо:

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

3 голосов
/ 16 сентября 2009

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

Вы хотите использовать подготовленные операторы 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/

0 голосов
/ 16 сентября 2009

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

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

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