<
  • Главная
Статьи

Захист від CSRF атак в ASP.NET Core додатку »Блог Віталія Лещенко

  1. акт 1
  2. акт 2
  3. акт 3

У цьому пості я хочу розповісти про те, що таке CSRF (Cross-Site Request Forgery) атака і як від неї захиститися.

акт 1

Уявімо собі сайт інтернет банкінгу якогось вигаданого банку. Клієнт цього банку цілком легальним чином логинится на сайті, виконує ряд операцій і закриває сторінку Не зробивши вихід. Після цієї операції в браузері клієнта залишилася кука.

Клієнт обманним шляхом потрапляє на сайт шахраїв, які відправляють AJAX запит на сайт інтернет банкінгу із запитом про переведення певної суми грошей на рахунок шахраїв. Так як в браузері залишилася кука з сайту інтернет банкінгу, то вона люб'язно прикріплюється браузером до запиту шахраїв. Усе.

акт 2

Тепер спробуємо зрозуміти, що сталося.

Оскільки запит відправляється на інший домен, і ми не розглядаємо ситуацію XSS ін'єкції на сайті інтернет банкінгу, то браузер, за замовчуванням (якщо не налаштований CORS), не дасть прочитати відповідь від сервера. А нашим шахраям це по суті і не треба. Важливо, що сам запит був відправлений на сервер і оброблений. Тобто відбулося списання грошових коштів. Атаку можна вважати успішно виконаною.

акт 3

Перейдемо до захисту.

Для захисту від цієї атаки використовується 2 AntiForgery-токена. Один відправляється на клієнт у вигляді куки, а другий в прихованому полі в формі. Коли клієнт самостійно виконує запит на сайті інтернет банкінгу, то на сервер йдуть 2 токена. Один у формі або в заголовку, другий в Кука. Сервер перевіряє їх валідність і з разі недоброго повертає відповідь зі статусом 400.

Для початку змінимо клас Startup

public class Startup {public void ConfigureServices (IServiceCollection services) {// ... services.AddMvc (options => {options.Filters.Add (new AutoValidateAntiforgeryTokenAttribute ());}); }}

ASP.NET MVC за замовчуванням в кожну форму додає приховане поле такого виду:

<Input name = "__ RequestVerificationToken" type = "hidden" value = "CfEJ6IxjsTbAPh1AhIp ......... 5PEbMY4s-2ALCzGETVQe6VixWhh3WMMXzVSXJ3w">

і створює куку з ім'ям виду .AspNetCore.Antiforgery.leVP-PGSx2U

Цього достатньо для захисту форм створених ASP.NET MVC Core. А як бути з AJAX запитами?

Все просто. Додамо в файл _Layout.cshtml такий шматок коду:

@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf @functions {public string GetAntiXsrfRequestToken () {return Xsrf.GetAndStoreTokens (Context) .RequestToken; }} <Meta name = "requests-validation-token" content = "@ GetAntiXsrfRequestToken ()" />

Тепер модифікуємо скрипт відправки запиту на сервер:

function getRequestsValidationToken (): string {const key = "requests-validation-token"; const elements = document.getElementsByTagName ( "meta"); for (let i = 0; i <elements.length; i ++) {const element = elements.item (i); if (element.name == key) {return element.content; }} Return null; } Const token = getRequestsValidationToken (); if (token == null) {throw new Error ( "Can not read requests validation token"); } $ .Ajax ({type: 'POST', url: url, headers: { "RequestVerificationToken": token,} // OR // beforeSend: function (xhr) {// xhr.setRequestHeader ( "RequestVerificationToken", token) ; //}}). done (function (data) {alert (data);});

Уважний читач зараз може задати питання: якщо сам токен знаходиться в тілі сторінки, то, що заважає зловмисникам зробити GET запит нашої сторінки і прочитати цей токен? Може, але браузер скаже: Failed to load https://www.vitaliy.org/: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://hacker-site.com' is therefore not allowed access.

Якщо сайт працює на декількох серверах (в фермі або в докері), то для того, щоб один сервер зміг розшифрувати токен, створений іншим сервером, необхоідмо налаштувати DataProtection. У моєму випадку це зроблено за допомогою шаринга ключа шіфорванія в Redis .

using Microsoft.AspNetCore.DataProtection; public void ConfigureServices (IServiceCollection services) {var redis = ConnectionMultiplexer.Connect (Configuration.GetConnectionString ( "RedisConnection")); services.AddDataProtection (). PersistKeysToRedis (redis, Configuration [ "Services: Redis: Key"]); }

PS: що ще треба зробити? налаштувати Content-Security-Policy і боротися з XSS. Але, це вже інша історія ...

А як бути з AJAX запитами?


Новости
  • Виртуальный хостинг

    Виртуальный хостинг. Возможности сервера распределяются в равной мере между всеми... 
    Читать полностью

  • Редизайн сайта

    Редизайн сайта – это полное либо частичное обновление дизайна существующего сайта.... 
    Читать полностью

  • Консалтинг, услуги контент-менеджера

    Сопровождение любых интернет ресурсов;- Знание HTML и CSS- Поиск и обновление контента;-... 
    Читать полностью

  • Трафик из соцсетей

    Сравнительно дешевый способ по сравнению с поисковым и контекстным видами раскрутки... 
    Читать полностью

  • Поисковая оптимизация

    Поисковая оптимизация (англ. search engine optimization, SEO) — поднятие позиций сайта в результатах... 
    Читать полностью