Модераторы: LSD
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> защита от sql injection 
:(
    Опции темы
alexandrnv
  Дата 1.11.2008, 16:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 4.10.2008

Репутация: нет
Всего: нет



Подскажите, пожалуйста, по поводу sql injection. 
Какие символы нужно проверять в строке, которая передаётся через адресную строку браузера (например, http://my/test.aspx?name=MyVariable)?
Знаю, что одинарные кавычки нужно обязательно проверять. Нужно ли что-нибудь ещё?
Вот, написал для примера кусок кода. Безопасен ли он с точки зрения sql injection? (одинарные кавычки в нем заменяются на двойные)

Код

string name = Request.QueryString["name"];
name = name.Replace( '\'', '"'); // замена ' на "
string SQL = "SELECT * FROM test WHERE name = " + name;
OleDbCommand cmd = new OleDbCommand(SQL, conn);
OleDbDataReader dr = cmd.ExecuteReader();



И ещё вопросик. Правда больше по C#, чем по БД.
Есть ли принципиальная разница (кроме удобства, стиля) между использованием переменных прямо в строке (как в примере выше) и использованием параметров
Код

cmd.Parameters.Add("name", OleDbType.VarChar).Value = name;


Заранее спасибо

Это сообщение отредактировал(а) alexandrnv - 1.11.2008, 16:48
PM MAIL   Вверх
Zloxa
Дата 1.11.2008, 17:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 11
Всего: 161



Все очень зависит от целевой платформы.
Пример кода под номером один - первый пункт в списке "за что Oralce DBA готовы убивать программистов"
Пример кода под номером два - прекрасный пример защиты от sql injection


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
alexandrnv
Дата 1.11.2008, 17:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 4.10.2008

Репутация: нет
Всего: нет



Цитата(Zloxa @ 1.11.2008,  17:04)
Все очень зависит от целевой платформы.
Пример кода под номером один - первый пункт в списке "за что Oralce DBA готовы убивать программистов"
Пример кода под номером два - прекрасный пример защиты от sql injection

Zloxa Извини, но ты не ответил на мои вопросы.
Где именно в первом коде дырка?
По поводу второго (использования параметра). Я проверял (если меня не проглючило) и всё равно sql injection работает,то есть одинарная кавычка ломает запрос (если её не заменять на ").

ps) целевая платформа - это что?
БД - oracle, как ты уже понял.


Это сообщение отредактировал(а) alexandrnv - 1.11.2008, 17:12
PM MAIL   Вверх
skyboy
Дата 1.11.2008, 17:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 5
Всего: 260



Цитата(alexandrnv @  1.11.2008,  16:11 Найти цитируемый пост)
ps) целевая платформа - это что?

в твоем случае - Oracle. только ты неожиданно как-то промолчал про это в первом посте. прям, партизан smile а меж тем, способы защиты от sql injection зависят от двух вещей:
а) кто является клиентом, исполняющим запрос - язык программирования, специализированная программа, внутренние механизмі СУБД(к примеру, механизму импорта из CSV бесполезно скармливать SQL-запросы с любыми кавычками smile)
б) какая целевая СУБД
Цитата(alexandrnv @  1.11.2008,  16:11 Найти цитируемый пост)
Я проверял (если меня не проглючило) и всё равно sql injection работает,то есть одинарная кавычка ломает запрос (если её не заменять на ").

странно. приведи код.
PM MAIL   Вверх
alexandrnv
Дата 1.11.2008, 20:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 4.10.2008

Репутация: нет
Всего: нет



Цитата(skyboy @ 1.11.2008,  17:37)
способы защиты от sql injection зависят от двух вещей:
а) кто является клиентом, исполняющим запрос - язык программирования, специализированная программа, внутренние механизмі СУБД

В общем, веб приложение (работаю в Visual Studio 2005). 
Пользователи передают параметры через адресную строку браузера.
Например, http://my/test.aspx?id=4

Вот в чем вопрос: 
если код обработки такой же, как в первом посте:
Код

string SQL_query = "SELECT * FROM test WHERE id = " + id;

,где string id = Request["id"].Replace( '\'', '"'); // замена ' на "

Подвержен ли данный конкретный код sql-injection? 

ps) Насчет использования параметров... Может меня проглючило, хз. ещё раз проверю, как на работу выйду. Дому у меня сервер оракла не стоит.

PM MAIL   Вверх
Zloxa
Дата 1.11.2008, 20:38 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 11
Всего: 161



Цитата(alexandrnv @  1.11.2008,  17:11 Найти цитируемый пост)
Где именно в первом коде дырка

В подходе.
Ты знаешь правильное решение, но от чего то им пренебрегаешь.

Одна из особенностей оракла - крайне высокая стоимость операции первичного разбора SQL операторов (Hard Parse). Оракл выстраивает целое дерево возможных вариантов выполнения запроса, оценивает каждый, выбирает из множества планов наиболее оптимальный. Все это сопровождается весьма большим количеством блокировок на уровне регистров системы. Единожды построив план для запроса, чтобы избегать этой операции впредь, оракл сохраняет запрос и выбранный план в пул запросов, в котором он хранится до тех пор пока не будет вытеснен другими планами либо не будут изменены связанные с запросом объекты схемы. В случае, если поступает в точности такой же запрос, оракл не производит дорогой операции первичного разбора. Для выбора плана, он использует готовый из пула. Сравнение идентичности запросов производится без разбора, по исходному тексту запроса.

Таким образом запрос select *  from table where name = 'Вася' и select *  from table where name = 'Петя', для оракла это разные запросы, для каждого из них будет выполнен Hard Prarse. Каждый из этих запросов будет размещен в Shared Pool, каждый из этих запросов может вытеснить из пула другие запросы, чем инициирует их повторный разбор в будущем. Я уже упоминал что разбор сопровождается весьма большим количеством системных блокировок. Изза этого, две сесии, одновременно выполняющие Hard Parce - сериализуются. Это значит что если одна паршивая сессия начнёт массово фигачить такого рода запросы, она завалит производительность всей системы в целом, даже если другие приложения базы будут спроектированы корректно. 

Избежать подобной ситуации, весьма просто. Для этого достаточно использовать связанные переменные. Тогда запросы преобразуются к виду select *  from table where name =:param.  В виду всего вышеописанного, использование связанных переменных в оракле это даже не правило хорошего тона. Это жизненная необходимость. Именно поэтому программист, который засрет Shared Pool в оракле, у DBA пойдет по расстрельной статье.

"Использование связанных переменных" это так же ответ на вопрос как строить приложение так, чтобы не бояться инжектинга.

Каким образом ты смог повредить SQL используя связанные переменные, для меня загадка. Я это понял бы, если б ты имел возможность использовать substitution параметры, но помоему ADO не позволяет их использовать. Если таки позволяет, не рекомендовал бы их использовать на оракле, потому как они не для того предназначены, и использование их мало отличается от динамического формирования запроса, а вред этого, я уже попытался описать выше.




--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
alexandrnv
Дата 1.11.2008, 20:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 4.10.2008

Репутация: нет
Всего: нет



Цитата(Zloxa @ 1.11.2008,  20:38)
Цитата(alexandrnv @  1.11.2008,  17:11 Найти цитируемый пост)
Где именно в первом коде дырка

В подходе.
Ты знаешь правильное решение, но от чего то им пренебрегаешь.

Одна из особенностей оракла - крайне высокая стоимость операции первичного разбора SQL операторов (Hard Parse). Оракл выстраивает целое дерево возможных вариантов выполнения запроса, оценивает каждый, выбирает из множества планов наиболее оптимальный. Все это сопровождается весьма большим количеством блокировок на уровне регистров системы. Единожды построив план для запроса, чтобы избегать этой операции впредь, оракл сохраняет запрос и выбранный план в пул запросов, в котором он хранится до тех пор пока не будет вытеснен другими планами либо не будут изменены связанные с запросом объекты схемы. В случае, если поступает в точности такой же запрос, оракл не производит дорогой операции первичного разбора. Для выбора плана, он использует готовый из пула. Сравнение идентичности запросов производится без разбора, по исходному тексту запроса.

Таким образом запрос select *  from table where name = 'Вася' и select *  from table where name = 'Петя', для оракла это разные запросы, для каждого из них будет выполнен Hard Prarse. Каждый из этих запросов будет размещен в Shared Pool, каждый из этих запросов может вытеснить из пула другие запросы, чем инициирует их повторный разбор в будущем. Я уже упоминал что разбор сопровождается весьма большим количеством системных блокировок. Изза этого, две сесии, одновременно выполняющие Hard Parce - сериализуются. Это значит что если одна паршивая сессия начнёт массово фигачить такого рода запросы, она завалит производительность всей системы в целом, даже если другие приложения базы будут спроектированы корректно. 

Избежать подобной ситуации, весьма просто. Для этого достаточно использовать связанные переменные. Тогда запросы преобразуются к виду select *  from table where name =:param.  В виду всего вышеописанного, использование связанных переменных в оракле это даже не правило хорошего тона. Это жизненная необходимость. Именно поэтому программист, который засрет Shared Pool в оракле, у DBA пойдет по расстрельной статье.

"Использование связанных переменных" это так же ответ на вопрос как строить приложение так, чтобы не бояться инжектинга.

Каким образом ты смог повредить SQL используя связанные переменные, для меня загадка. Я это понял бы, если б ты имел возможность использовать substitution параметры, но помоему ADO не позволяет их использовать. Если таки позволяет, не рекомендовал бы их использовать на оракле, потому как они не для того предназначены, и использование их мало отличается от динамического формирования запроса, а вред этого, я уже попытался описать выше.

 smile  smile 
Я не всё понял, что ты сказал. Но мне уже страшно =)
Спасибо за информацию. Отныне и навсегда торжественно клянусь использовать только параметризированные запросы =)

Но всё таки (да, я упертый) Данный конкретный код подвержен уязвимости ? Если да, то как?

Цитата

Я это понял бы, если б ты имел возможность использовать substitution параметры, но помоему ADO не позволяет их использовать.


Первый код в самом первом посте - вот пример использования substitution-параметра. Да, я так делать не буду. Но всё таки, есть ли дырка? (не считая потери производительности)
PM MAIL   Вверх
Zloxa
Дата 1.11.2008, 22:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 11
Всего: 161



Цитата(alexandrnv @  1.11.2008,  20:57 Найти цитируемый пост)
Да, я так делать не буду. Но всё таки, есть ли дырка

Я бы на твоем месте, вместо замены символа ковычка на символ двойная_кавычка(что есть суть искажение данных полученных от пользователя) заменял бы символ кавычка на два символа кавычки, и результирующую строку заворачивал бы в кавычки. И спал бы спокойно. Если инжектинг и произошел бы, то виной был бы не я а оракл. При наличии проплаченного саппорта (лицензионности),что есть суть гемор заказчика(работодателя), с ораклом корп. можно было бы  и побадатсья, если чо.

Я не знаю метода Replace строки сишарп, но если она позволяет менять чар на строку, это выглядело бы так
Код

string name = Request.QueryString["name"];
name = name.Replace( '\'', '\'\''); // замена ' на ''
string SQL = "SELECT * FROM test WHERE name = \'" + name+"\'";
OleDbCommand cmd = new OleDbCommand(SQL, conn);
OleDbDataReader dr = cmd.ExecuteReader();


PS
Цитата(alexandrnv @  1.11.2008,  20:57 Найти цитируемый пост)
Отныне и навсегда 

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

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

"Всему свое время, всему свое место..... и место это - колледж"(с)Йужный парк.

Это сообщение отредактировал(а) Zloxa - 1.11.2008, 22:59


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
DKroshkin
Дата 24.11.2008, 01:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 25
Регистрация: 28.9.2007

Репутация: нет
Всего: нет



Цитата(alexandrnv @ 1.11.2008,  20:57)
Цитата

Первый код в самом первом посте - вот пример использования substitution-параметра. Да, я так делать не буду. Но всё таки, есть ли дырка? (не считая потери производительности)


string name = Request.QueryString["name"];
name = name.Replace( '\'', '"'); // замена ' на "
string SQL = "SELECT * FROM test WHERE name = " + name;
OleDbCommand cmd = new OleDbCommand(SQL, conn);
OleDbDataReader dr = cmd.ExecuteReader();

Попробуйте поиграться передавая в качестве параметра запроса символ точки с запятой и потом еще один запрос.
Типа http://my/test.aspx?name=Вася Пупкин;select * from users)

Или еще глубже если вместо Вася Пупкин вызывать функции, например
upper(Вася Пупкин)
Думаю это простенькая функция, но если знать более глубоко Oracle, то думаю лазейку найти не составит труда.

Солидарен с DBA, что за такой код стоит ломать руки и не только руки. smile

Прошу прощения, если цитирование плохо получилось
PM MAIL   Вверх
Zloxa
Дата 24.11.2008, 09:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 11
Всего: 161



Цитата(DKroshkin @  24.11.2008,  01:38 Найти цитируемый пост)
Попробуйте поиграться передавая в качестве параметра запроса символ точки с запятой и потом еще один запрос.
Типа http://my/test.aspx?name=Вася Пупкин;select * from users)

НУ и толку то?
В результате будет получен запрос
Код

"SELECT * FROM test WHERE name = 'Вася Пупкин;select * from users'



--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
DKroshkin
Дата 24.11.2008, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 25
Регистрация: 28.9.2007

Репутация: нет
Всего: нет



Цитата(Zloxa @ 24.11.2008,  09:43)
НУ и толку то?
В результате будет получен запрос
Код

"SELECT * FROM test WHERE name = 'Вася Пупкин;select * from users'

точка с запятой как разделитель запросов.
А если вместо select * from users, подставить что-то типа
create user testuser identified by testuser
+ добавить еще прав этому тестовому пользователю.
Понимаете к чему я клоню?
PM MAIL   Вверх
Zloxa
Дата 24.11.2008, 17:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Чо?
****


Профиль
Группа: Завсегдатай
Сообщений: 3473
Регистрация: 12.9.2008

Репутация: 11
Всего: 161



Цитата(DKroshkin @  24.11.2008,  16:56 Найти цитируемый пост)
Понимаете к чему я клоню? 

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

Вы читали процитированный Вами SQL? В нем точказапятая является не разделителем команд а символом строки. 

Это сообщение отредактировал(а) Zloxa - 24.11.2008, 17:46


--------------------
Достоверно известно, что 89% людей доверяют статистике взятой с потолка smile
PM   Вверх
DKroshkin
Дата 24.11.2008, 20:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 25
Регистрация: 28.9.2007

Репутация: нет
Всего: нет



Цитата(Zloxa @ 24.11.2008,  17:43)
Цитата(DKroshkin @  24.11.2008,  16:56 Найти цитируемый пост)
Понимаете к чему я клоню? 

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

Вы читали процитированный Вами SQL? В нем точказапятая является не разделителем команд а символом строки.

Проблема с цитированием

Исходный пример, не содержит одинарных кавычек.

string name = Request.QueryString["name"];
name = name.Replace( '\'', '"'); // замена ' на "
string SQL = "SELECT * FROM test WHERE name = " + name;
OleDbCommand cmd = new OleDbCommand(SQL, conn);
OleDbDataReader dr = cmd.ExecuteReader();


PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Общие вопросы по базам данных"
LSD
Zloxa

Данный форум предназначен для обсуждения вопросов о базах данных не попадающих под тематику других форумов:

  • вопросам по СУБД для которых нет отдельных подфорумов
  • вопросам которые затрагивают несколько разных СУБД (например проблема выбора)
  • инструменты для работы с СУБД
  • вопросы проектирования БД
  • теоретически вопросы о СУБД

Данный форум не предназначен для:

  • вопросов о поиске разлиных БД (если не понимаете чем БД отличается от СУБД то: а) вам не сюда; б) Google в помощь)
  • обсуждения проблем с доступом к СУБД из различных ЯП (для этого есть соответсвующие форумы по каждому ЯП)
  • обсуждения проблем с написание SQL запросов, для этого есть форум Составление SQL-запросов
  • просьб о написании курсовой, реферата и т.п., для этого есть Центр помощи или фриланс биржа
  • объявлений о найме специалистов, для этого есть раздел Объявления о найме специалистов

Если вы не соблюдаете эти правила, не удивляйтесь потом не найдя свою тему/сообщение. ;)


Полезные советы:

При написании сообщения постарайтесь дать теме максимально понятное название. В теме максимально подробно опишите проблему. Если применимо укажите: название базы данных и версии (MySQL 4.1, MS SQL Server 2000 и т.п.); используемых язык программирования; способа доступа (ADO, BDE и т.д.); сообщения об ошибках.

Для вставки кода используйте теги [code=sql] [/code].

Литературу по базам данных можно поискать здесь.

Действия модераторов можно обсудить здесь.


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, LSD, Zloxa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | СУБД, общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0554 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.