![]() |
|
Модераторы: LSD |
![]()
|
|
| alexandrnv |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 4.10.2008 Репутация: нет Всего: нет |
Подскажите, пожалуйста, по поводу sql injection.
Какие символы нужно проверять в строке, которая передаётся через адресную строку браузера (например, http://my/test.aspx?name=MyVariable)? Знаю, что одинарные кавычки нужно обязательно проверять. Нужно ли что-нибудь ещё? Вот, написал для примера кусок кода. Безопасен ли он с точки зрения sql injection? (одинарные кавычки в нем заменяются на двойные)
И ещё вопросик. Правда больше по C#, чем по БД. Есть ли принципиальная разница (кроме удобства, стиля) между использованием переменных прямо в строке (как в примере выше) и использованием параметров
Заранее спасибо Это сообщение отредактировал(а) alexandrnv - 1.11.2008, 16:48 |
||||
|
|||||
| Zloxa |
|
|||
|
Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 11 Всего: 161 |
Все очень зависит от целевой платформы.
Пример кода под номером один - первый пункт в списке "за что Oralce DBA готовы убивать программистов" Пример кода под номером два - прекрасный пример защиты от sql injection -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка |
|||
|
||||
| alexandrnv |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 4.10.2008 Репутация: нет Всего: нет |
Zloxa Извини, но ты не ответил на мои вопросы. Где именно в первом коде дырка? По поводу второго (использования параметра). Я проверял (если меня не проглючило) и всё равно sql injection работает,то есть одинарная кавычка ломает запрос (если её не заменять на "). ps) целевая платформа - это что? БД - oracle, как ты уже понял. Это сообщение отредактировал(а) alexandrnv - 1.11.2008, 17:12 |
|||
|
||||
| skyboy |
|
|||
|
неОпытный ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9820 Регистрация: 18.5.2006 Где: Днепропетровск Репутация: 5 Всего: 260 |
в твоем случае - Oracle. только ты неожиданно как-то промолчал про это в первом посте. прям, партизан а) кто является клиентом, исполняющим запрос - язык программирования, специализированная программа, внутренние механизмі СУБД(к примеру, механизму импорта из CSV бесполезно скармливать SQL-запросы с любыми кавычками б) какая целевая СУБД
странно. приведи код. |
|||
|
||||
| alexandrnv |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 4.10.2008 Репутация: нет Всего: нет |
В общем, веб приложение (работаю в Visual Studio 2005). Пользователи передают параметры через адресную строку браузера. Например, http://my/test.aspx?id=4 Вот в чем вопрос: если код обработки такой же, как в первом посте:
,где string id = Request["id"].Replace( '\'', '"'); // замена ' на " Подвержен ли данный конкретный код sql-injection? ps) Насчет использования параметров... Может меня проглючило, хз. ещё раз проверю, как на работу выйду. Дому у меня сервер оракла не стоит. |
||||
|
|||||
| Zloxa |
|
|||
|
Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 11 Всего: 161 |
В подходе. Ты знаешь правильное решение, но от чего то им пренебрегаешь. Одна из особенностей оракла - крайне высокая стоимость операции первичного разбора 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% людей доверяют статистике взятой с потолка |
|||
|
||||
| alexandrnv |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 17 Регистрация: 4.10.2008 Репутация: нет Всего: нет |
Я не всё понял, что ты сказал. Но мне уже страшно =) Спасибо за информацию. Отныне и навсегда торжественно клянусь использовать только параметризированные запросы =) Но всё таки (да, я упертый) Данный конкретный код подвержен уязвимости ? Если да, то как?
Первый код в самом первом посте - вот пример использования substitution-параметра. Да, я так делать не буду. Но всё таки, есть ли дырка? (не считая потери производительности) |
||||
|
|||||
| Zloxa |
|
|||
|
Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 11 Всего: 161 |
Я бы на твоем месте, вместо замены символа ковычка на символ двойная_кавычка(что есть суть искажение данных полученных от пользователя) заменял бы символ кавычка на два символа кавычки, и результирующую строку заворачивал бы в кавычки. И спал бы спокойно. Если инжектинг и произошел бы, то виной был бы не я а оракл. При наличии проплаченного саппорта (лицензионности),что есть суть гемор заказчика(работодателя), с ораклом корп. можно было бы и побадатсья, если чо. Я не знаю метода Replace строки сишарп, но если она позволяет менять чар на строку, это выглядело бы так
PS "Отныне и на всегда" - не обязательно. Если ты делаешь разовую выгрузку или залитие, если ты запрос пишешь вручную, использование параметрических запросов, помимо того что может быть не удобно, может ещё и быть не оправданно. Однако если ты пишешь систему, которая будет изо дня в день от часа к часу засирать Шаред Пулл, я тремя руками поддержу того админа, который решит тебя расстрелять, если он меня призовет в присяжные. "Всему свое время, всему свое место..... и место это - колледж"(с)Йужный парк. Это сообщение отредактировал(а) Zloxa - 1.11.2008, 22:59 -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка |
|||
|
||||
| DKroshkin |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 25 Регистрация: 28.9.2007 Репутация: нет Всего: нет |
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, что за такой код стоит ломать руки и не только руки. Прошу прощения, если цитирование плохо получилось |
||||
|
|||||
| Zloxa |
|
||||
|
Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 11 Всего: 161 |
НУ и толку то? В результате будет получен запрос
-------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка |
||||
|
|||||
| DKroshkin |
|
||||
|
Новичок Профиль Группа: Участник Сообщений: 25 Регистрация: 28.9.2007 Репутация: нет Всего: нет |
точка с запятой как разделитель запросов. А если вместо select * from users, подставить что-то типа create user testuser identified by testuser + добавить еще прав этому тестовому пользователю. Понимаете к чему я клоню? |
||||
|
|||||
| Zloxa |
|
|||
|
Чо? ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 3473 Регистрация: 12.9.2008 Репутация: 11 Всего: 161 |
Понимаю, но не понимаю как это возможно, если мы обрамим это кавычками, при этом все кавычки, упоминающиеся в исходной строке - заводим. Вы читали процитированный Вами SQL? В нем точказапятая является не разделителем команд а символом строки. Это сообщение отредактировал(а) Zloxa - 24.11.2008, 17:46 -------------------- Достоверно известно, что 89% людей доверяют статистике взятой с потолка |
|||
|
||||
| DKroshkin |
|
|||
|
Новичок Профиль Группа: Участник Сообщений: 25 Регистрация: 28.9.2007 Репутация: нет Всего: нет |
Проблема с цитированием Исходный пример, не содержит одинарных кавычек. 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(); |
|||
|
||||
![]()
|
| Правила форума "Общие вопросы по базам данных" | |
|
|
Данный форум предназначен для обсуждения вопросов о базах данных не попадающих под тематику других форумов:
Данный форум не предназначен для:
Если вы не соблюдаете эти правила, не удивляйтесь потом не найдя свою тему/сообщение.
Полезные советы: Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, LSD, Zloxa. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | СУБД, общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |