WEb практикум. Web'cepbep
Скачать 4.76 Mb.
|
Защита от инъекции в .NET Для работы с базами данных в C# есть класс Sqlcommand, которому нужна строка с SQL-запросом и объект подключения к базе данных. string sql = "select * from user where username= @u"; SqlCommand cmd = new SqlCommand(sql, connection); cmd.Parameters.Add( new SqlParameter() { ParameterName = "u", Value = "admin" } ); SqlDataReader reader = cmd.ExecuteReader(); Если в PHP параметры начинаются с двоеточия, то в C# — с символа @, после чего идет имя параметра. Теперь мы должны предоставить параметру значение. Параметры связываются со значениями в свойстве Parameters. В случае с C# правило защиты от SQL Injection остается тем же самым - используем параметры и в SQL-запросе не используем + для того, чтобы получить финальный запрос. Например, следующая строка подвержена уязвимости, если переменная u будет содержать значение, на которое может повлиять пользователь, то есть если мы получаем его от пользователя: string sql = "select * from user where username = " + u; Начиная с C# 6, в языке появилась поддержка интерполяции строк, — это когда переменные можно вставлять прямо в текст строки: string sql = $"select * from user where username= {u}"; Казалось бы, нет знаков сложения, нет никакого объединения, и, по идее, у нас не должно быть уязвимости, но, к сожалению, это не так: интерполяция строк не защищает от инъекции SQL, поэтому используйте параметры, только параметры. ГЛАВА 7 CSRF, или XSRF-уязвимость CSRF (cross-site request forgery или межсайтовая подделка запроса), также известна как XSRF — достаточно серьезная уязвимость, которая стала популярной в 2010-х годах, хотя первые упоминания датируются где-то началом двухтысячных. Идея атаки заключается в том, что пользователь выполняет какое-то действие на сайте X, но реально они направляются на сайт Y, и если пользователь реально зарегистрирован на этом сайте, то результат может быть достаточно плачевным. Примеры межсайтовой атаки Рассмотрим самый простой и для начала безобидный пример CSRF-атаки. На моем сайте есть страница поиска https://www.flenov.info/search/index, и чтобы эта страница отобразила результат поиска какого-то текста, достаточно методом get передать ей параметр search и после знака равно установить значение, например: https://www.flenov.info/search/index?search=test Этот URL заставит мой сайт найти все заметки на сайте, где упоминается слово test. Если вы разместите эту ссылку на своем сайте и его посетители кликнут по этой ссылке, то вы заставите их выполнить действие поиска на моем сайте. Как я уже сказал, это безобидное действие, но оно все же произошло. Допустим, что у меня есть учетная запись на сайте банка и на сайте есть страница, где я могу управлять своей учетной записью, в том числе поменять пароль. Чтобы сделать это, нужно загрузить форму смены пароля, ввести новый пароль и сохранить его. А что, если я размещу форму для смены пароля на своем сайте, и она будет отправлять введенные пользователем данные на сайт банка по URL, который меняет пароль? Если я назову переменные так же, как они называются у банка, и если на атакуемом сервере нет защиты от межсайтовых скриптов, атака может завершиться успешно. Вот пример формы, которая отображает два поля для имени и пароля, и если пользователь кликнет на кнопку, то данные полетят на страницу /account/changepassword банка: Обратите внимание, что тут у формы action указывает на URL банка, а в самой форме три параметра: имя username для ввода пользователя, куда должны ввести имя; поле ввода fakepassword, куда пользователь будет указывать новый пароль, но имя поля специально так названо, потому что нам все равно, что туда введут, мы это хотим игнорировать; скрытое поле password, которое содержит значение xyz, и именно имя этого поля должно совпадать с тем именем, которое ожидает банк. Так что мы поменяем пароль на xyz. Итак, располагаем эту форму у себя на сайте и начинаем нагонять жертв на страницу. Если атакуемый пользователь авторизован в данный момент на сайте и на сервере нет защиты, то при отправке этой формы пароль смениться на xyz. Единственная проблема — какое будет имя пользователя? Мы знаем пароль, потому что он прописан прямо в коде, а вот имя пользователя мы можем не знать. Эта проблема решаема. С помощью JavaScript можно без проблем по нажатию кнопки направить на свой сервер дополнительный запрос, который сообщит хакеру, какое имя пользователя мы поймали. Таким образом по нажатию кнопки будет отправляться два запроса: один — банку для смены пароля и еще один — на сайт хакера, чтобы сообщить имя пользователя жертвы. Слишком много если: пользователь должен быть зарегистрирован, он должен быть авторизован, сайт должен не иметь защиты. Однако в начале 2000-х годов это была не проблема. Сессии даже у банков были бесконечными, главное, чтобы человек был зарегистрирован. В США не так много крупных банков. В Канаде еще недавно банки можно было пересчитать на пальцах одной руки (их было четыре), так что вероятность, что пользователь пользуется одним из них очень высока. Захватив управление финансовым аккаунтом, можно украсть его деньги. Даже если пароль недоступен, хакеры могут использовать подобную атаку, чтобы вызвать перевод денег на свой счет, поэтому даже если пароль не получится украсть, возможно удастся украсть деньги. А представьте, если подобная уязвимость будет найдена у Facebook, "ВКонтакте", "Одноклассниках", Google, Microsoft и т. д. Тут вероятность того, что кто-то зарегистрирован, очень высокая. Подобную атаку можно использовать и для осуществления распределенной DDoS- атаки на определенный сайт. Первое, что приходит в голову, — добавить в форму необходимость ввести текущий пароль, и если он введен неверно, то отказывать смене. Самая бесполезная защита, потому что хакер может добавить такое же поле у себя на сайте и заставить пользователя вводить не только имя и новый пароль, но и существующий. Можно добавить каптчу. Этот метод уже сработает, потому что хакер на свой сайт каптчу добавить не сможет. Хотя нет, он сможет, но это будет его каптча, и она не будет совпадать с оригинальным сайтом, если только... Если только каптча не является простой картинкой. Если это изображение, то хакер может с помощью JavaScript направить GET-запрос на сайт банка, найти URL с изображением каптчи и забрать его себе. Правда, обход каптчи зависит от того, как она реализована на сервере, далеко не каждую реализацию можно обойти. Самое простое, если каптча не привязана к определенной сессии пользователя. Мне доводилось видеть подобные реализации, когда пользователь загружал страницу, на сервере создавался код безопасности, который действовал примерно 5 минут, но этот код мог отправить кто угодно, не обязательно, чтобы это был тот же пользователь, кто изначально загрузил сайт. Это самый ужасный вариант каптчи, когда при загрузке страницы код просто сохраняется в базе без привязки к пользователю и любой пользователь может его использовать. В этом отношении Google-каптча более безопасна, ее так не обмануть. Тут нужно не просто загрузить страницу, чтобы на сервере сгенерировался код, но и выполнить определенные действия на странице: кликнуть "Я не робот" и выбрать картинки из списка по определенному шаблону. От загрузки страницы со стороны чужого сайта позволяет защититься и политика CORS — это когда мы контролируем, кто может обращаться к ресурсам сервера. Об этом поговорим в разд. 7.4. В любом случае каптча не самый лучший вариант просто потому, что, добавляя ее в каждую форму на сайте, можно вызвать негативный эффект у легальных пользователей. Я использую эту защиту для формы регистрации и добавления комментариев только потому, что обе функциональности очень сильно любят спамеры, которые ради того, чтобы оставить ссылки на сайты, готовы пойти на многое. Остальные формы лучше защищать другими методами. Хорошая защита Самая простая защита, которая может сработать, — проверка Referer. Когда пользователь загружает страницу, то браузер отправляет серверу в качестве одного из параметров еще и URL-страницы, с которой пользователь перешел на сайт или отправил данные. Если форма расположена на сайте хакера www.hacksite.ru и с него отправляется на сайт банка www.bankname/account/changepassword, то банк может проверить у текущего запроса параметр referer, и если он не совпадает с сайтом банка, а принадлежит кому-то другому, то запрос можно отклонить.
index?search=Test atrap.min.css . font-awesome.mln.css style.css?26 css?family=Caveat|Montserrat|Raleway:.. jquery.min.js ■ apl.js Щ bootstrap.min.js Щ default.js?1 | adsbygoogle.js Щ defaultlmagesm.png | headerimage.png 0 telegram-icon.png 0 tw-icon.png 0 yt-icon.png 3 ap-icon.png 3 sp-icon.png ' Request Headers Fnov. info :method: GET :path: /search/index?search=Test rscheme: https accept: text/html,application/xhtml+xml,application/xr accept-encoding: gzip, deflate, br accept-language: en-US,en;q=0.9, ru;q=0.8 cache-control: no-cache cookie: _ym_uid=1546536376946461143; fid=db2333d3-48ee 5:S=ALNI_MaTFXuPU2SKpOH05Evhz8HrHP9mZA; _utmz=184115 9C26; utmc=18411502; _gads=undefined; PHPSESSID=f7 1.10.1615080112 pra referer. https ://www ^el-LII'UJ. LIU UllliUlll Рис. 7.1. Referer в утилитах разработчика .flenov.info/ 1 |