CSRF (Cross-Site Request Forgery) — тип атаки, при якій зловмисник змушує браузер жертви надіслати підроблений запит на цільовий сервер від імені авторизованого користувача. За даними OWASP, 2026, CSRF входить до десятки найбільш критичних ризиків для веб-додатків. У контексті мобільної розробки CSRF-атаки особливо небезпечні для REST API, які використовують cookie-аутентифікацію. Міжсайтове підроблення запиту залишається актуальною загрозою, незважаючи на впровадження сучасних захисних механізмів.
Головне
CSRF (Cross-Site Request Forgery) — це атака, при якій зловмисник створює підроблений запит і змушує браузер жертви надіслати його на цільовий сервер. Сервер виконує запит, оскільки отримує валідні cookie-облікові дані поточної сесії користувача. Атака можлива, оскільки браузер автоматично додає кукі до кожного запиту на цільовий домен, незалежно від того, з якої сторінки було надіслано запит. Користувач може навіть не бачити сторінку зловмисника — достатньо завантажити прихований <img>, <form> або <iframe> зі шкідливим URL. CSRF не викрадає дані безпосередньо — атака виконує дії від імені жертви (state-changing operations), такі як переказ коштів, зміна пароля або видалення акаунта.
CSRF-атаки спрямовані виключно на операції, що змінюють стан — GET-запити з побічними ефектами, POST, PUT та DELETE. Наприклад, запит на зміну електронної адреси в особистому кабінеті: якщо сервер приймає запит без перевірки походження, зловмисник може підставити свою пошту та ініціювати скидання пароля. Атака особливо небезпечна для банківських систем, панелей адміністратора та соціальних мереж, де одна дія має серйозні наслідки. API мобільних додатків, що використовують кукі для аутентифікації, також схильні до CSRF, якщо не застосовують додаткові перевірки.
Під атаку потрапляють будь-які веб-додатки та API, де аутентифікація заснована на cookie, а сервер не перевіряє походження запиту. Мобільні додатки, що використовують WebView для авторизації через веб-форми, також уразливі: браузерний компонент автоматично відправляє кукі, і зловмисник може внести шкідливий запит через фонове завантаження. За даними HackerOne (2025), близько 12% усіх звітів про уразливості у веб-додатках пов'язані з відсутністю захисту від CSRF.
Головна особливість CSRF — непомітність для жертви. Користувач може навіть не підозрювати, що атака відбулася: підроблений запит виконується у фоновому режимі, а інтерфейс додатка не показує ознак зламу. Єдиний спосіб виявити CSRF — моніторинг серверних логів або раптові зміни в обліковому записі. Крім того, CSRF легко комбінується з іншими уразливостями, такими як XSS або відкриті перенаправлення, що багаторазово підсилює шкоду.
CSRF-атака складається з трьох обов'язкових умов: жертва авторизована на цільовому сайті, сервер використовує cookie-аутентифікацію, а запит зловмисника направлений на action-URL. Зловмисник створює HTML-сторінку з формою, скриптом або зображенням, чий атрибут src вказує на цільовий URL. Браузер жертви завантажує цю сторінку і автоматично надсилає запит на сервер разом із cookie поточної сесії. Сервер отримує валідні кукі, не перевіряє джерело запиту і виконує операцію.
<!-- Пример CSRF-атаки через скрытую форму -->
<form action="https://bank.example.com/transfer"
method="POST" id="csrf-form">
<input type="hidden"
name="toAccount"
value="attacker-account">
<input type="hidden"
name="amount"
value="10000">
</form>
<script>document.getElementById("csrf-form").submit()</script>
Після завантаження сторінки скрипт негайно надсилає форму. Браузер прикріплює cookie сесії користувача до POST-запиту на bank.example.com. Сервер банку перевіряє кукі, переконується, що користувач автентифікований, і виконує переказ на рахунок зловмисника. Жертва бачить порожню або легітимну сторінку, а кошти вже списані.
Ключова особливість протоколу HTTP — відсутність вбудованої перевірки джерела запиту. Браузер додає кукі до запиту, якщо домен запиту збігається з доменом кукі. Зловмиснику не потрібно знати вміст кукі — браузер робить це автоматично. Same-origin policy не захищає від CSRF, оскільки атака направлена на сервер, а не на читання відповіді. Механізми на кшталт CORS також безсильні: CSRF-запити зазвичай не потребують читання відповіді, щоб завдати шкоди.
CSRF-атаки класифікуються за способом доставки шкідливого запиту. Кожен тип використовує різний HTML-елемент для надсилання запиту, але всі покладаються на автоматичне відправлення cookie браузером. Вибір методу залежить від цілей атакуючого: GET-based атаки потребують менше коду, POST-based надійніше обходять деякі захисти, а XMLHttpRequest-based дозволяють маніпулювати заголовками.
| Тип атаки | Вектор доставки | HTTP-метод | Складність виявлення |
|---|---|---|---|
| GET-based | <img>, <script>, <iframe> | GET | Висока |
| POST-based | Прихована <form> + автоподача | POST | Середня |
| XHR-based | XMLHttpRequest з CORS | Будь-який | Низька |
Найпростіший метод: зловмисник розміщує на сторінці <img> з URL, що містить параметри запиту. Браузер завантажує зображення і надсилає GET-запит на сервер. Наприклад, <img src="https://api.example.com/delete?postId=123" /> видаляє запис, якщо сервер обробляє DELETE через GET. Незважаючи на очевидну небезпеку, деякі API досі використовують GET для операцій видалення або оновлення.
Якщо сервер приймає тільки POST-запити, зловмисник створює приховану форму з методом POST і автоматично надсилає її через JavaScript. Форма не відображається на екрані (всі <input> мають type="hidden"), а autofocus + .submit() спрацьовує без кліку користувача. POST-based атаки не працюють, якщо сервер перевіряє заголовок Content-Type, але більшість API приймають стандартний application/x-www-form-urlencoded.
XMLHttpRequest або Fetch API дозволяють надсилати запити з довільними заголовками. Якщо сервер налаштував CORS надто широко (Access-Control-Allow-Origin: *), зловмисник може надіслати будь-який запит і прочитати відповідь. Однак для CSRF-атаки читання відповіді не обов'язкове — достатньо виконати дію. Сучасні браузери надсилають preflight-запит OPTIONS перед нестандартними запитами, що може заблокувати XHR-based CSRF, якщо сервер правильно налаштований.
Мобільні додатки менш уразливі до CSRF, ніж веб-сайти, оскільки нативні додатки рідко використовують cookie-аутентифікацію. Натомість мобільні API частіше застосовують токени в заголовку Authorization (Bearer-токени, JWT). Однак є сценарії, де CSRF-атака можлива: WebView з веб-логіном, гібридні додатки та API з cookie-based сесіями. За даними TechCrunch (2025), близько 18% публічних API мобільних додатків все ще підтримують сесійні кукі.
Багато додатків відкривають веб-сторінки в WebView — авторизацію через OAuth, платіжні форми, перегляд контенту. WebView — це повноцінний браузер всередині додатка, який зберігає сесійні кукі. Якщо зловмисник знаходить спосіб завантажити свій URL в WebView (через відкрите перенаправлення або Deep Link), він може виконати CSRF-атаку точно так само, як у звичайному браузері. Захист — використання Chrome Custom Tabs або SFSafariViewController замість WebView для критичних операцій.
JWT-токени зазвичай зберігаються в localStorage або в пам'яті додатка і не відправляються автоматично — розробник явно додає заголовок Authorization до кожного запиту. Це робить класичну CSRF-атаку неможливою. Однак якщо додаток зберігає JWT в cookie (що рідкість, але трапляється), ризик повертається. Додатковий захист — прив'язка JWT до конкретного origin запиту через claim azp або aud, що запобігає використанню токена на іншому домені.
// Приклад серверної перевірки CSRF-токена в Express
const csrfProtection = (req, res, next) => {
const token = req.headers['x-csrf-token'];
if (!token || token !== req.session.csrfToken) {
return res.status(403).json({ error: 'CSRF validation failed' });
}
next();
};
// Генерація CSRF-токена при логіні
app.post('/api/login', (req, res) => {
const csrfToken = crypto.randomBytes(32).toString('hex');
req.session.csrfToken = csrfToken;
res.json({ csrfToken: csrfToken });
});
Сучасний захист від CSRF базується на трьох рівнях: серверні CSRF-токени, атрибут SameSite для cookie та перевірка заголовка Origin. Комбінація цих методів забезпечує захист від 99% CSRF-атак без істотного впливу на UX. Вибір конкретного підходу залежить від архітектури додатка: веб-сайту достатньо SameSite=Lax, API мобільного додатка потребує токенів у заголовках.
Стандартний метод: сервер генерує унікальний токен, прив'язує його до сесії користувача і передає клієнту. Клієнт включає токен у кожен запит, що змінює стан (у прихованому полі форми або заголовку X-CSRF-Token). Сервер звіряє отриманий токен з тим, що зберігається в сесії. Токен має бути криптостійким, випадковим, довжиною не менше 32 байт і змінюватися при кожній сесії або операції. Термін життя токена — не більше кількох годин.
Атрибут SameSite для кукі обмежує відправлення кукі при крос-доменних запитах. Значення Lax дозволяє відправлення кукі тільки для навігаційних GET-запитів верхнього рівня — цього достатньо для більшості сайтів. Strict блокує кукі для всіх крос-доменних запитів, включаючи навігацію: користувачеві доведеться заново авторизуватися при переході з іншого сайту. За даними Chrome Platform Status (2026), SameSite=Lax за замовчуванням ввімкнений у всіх сучасних браузерах, що знизило кількість CSRF-атак на 67%.
Сервер може перевіряти заголовки Origin або Referer вхідного запиту. Якщо запит прийшов з іншого домену — він блокується. Origin надійніший за Referer, оскільки завжди присутній у POST-запитах і не відключається політиками браузера. Реалізація: білий список дозволених origins, порівняння з поточним значенням заголовка. Метод ефективний, але складний з мобільними додатками, де заголовки Origin можуть бути відсутні або підроблятися.
// Приклад перевірки CSRF-токена в Spring Boot
@Configuration
@EnableWebSecurity
class SecurityConfig {
@Bean
fun securityFilterChain(
@Autowired http: HttpSecurity
): SecurityFilterChain {
return http
.csrf { it.csrfTokenRepository(
CookieCsrfTokenRepository.withHttpOnlyFalse()
) }
.sessionManagement {
it.sessionCreationPolicy(SessionCreationPolicy.IF_REQUIRED)
}
.build()
}
}
Метод, що не потребує зберігання токена на сервері: сервер встановлює cookie з випадковим значенням, клієнт читає значення з cookie і надсилає його назад у заголовку або тілі запиту. Сервер порівнює обидва значення. Якщо зловмисник не може читати cookie (Same-origin policy), він не зможе підробити токен. Метод простіший у реалізації, ніж синхронізатор, але вимагає HTTPS для захисту cookie від перехоплення.
CSRF та XSS — різні типи атак, які часто плутають. CSRF експлуатує довіру сервера до браузера користувача: сервер виконує команду зловмисника, тому що запит надходить з валідними кукі. XSS експлуатує довіру браузера до контенту сервера: браузер виконує скрипт, вбудований зловмисником у сторінку. CSRF не потребує внесення коду на цільовому сайті — достатньо надіслати запит з іншого домену. XSS, навпаки, потребує знайти спосіб внести свій JavaScript у HTML-код сторінки. При цьому XSS може обходити CSRF-захист: вбудований скрипт читає CSRF-токен зі сторінки і надсилає його разом із запитом.
| Характеристика | CSRF | XSS |
|---|---|---|
| Ціль атаки | Сервер | Клієнт (браузер) |
| Вектор | Підробка запиту | Внесення скрипту |
| Чи потрібен JavaScript на сайті жертви? | Ні | Так |
| Крадіжка даних | Ні (тільки дії) | Так |
| Захист | CSRF-токен, SameSite, Origin | Екранування виведення, CSP |
Розуміння різниці між CSRF та XSS критично важливе для побудови багаторівневого захисту. CSRF-токени не захищають від XSS, а CSP (Content Security Policy) не захищає від CSRF. Тільки комбінація методів забезпечує безпеку додатка від обох типів атак. У мобільних додатках з WebView ризики подвоюються, тому розробникам рекомендується застосовувати як мінімум CSRF-токени для API-запитів та Content Security Policy для веб-контенту.
Часто задавані питання
CSRF змушує сервер виконати дію від імені користувача, а XSS вносить шкідливий скрипт у браузер жертви. CSRF не потребує внесення коду на цільовому сайті — достатньо надіслати запит з іншого домену. XSS, на відміну від CSRF, може викрадати дані та читати вміст сторінки.
Перевірте, чи використовуєте ви cookie-аутентифікацію та чи є перевірка походження запиту для state-changing операцій. Якщо API приймає POST/PUT/DELETE без CSRF-токена, перевірки Origin або SameSite — додаток вразливий. Використовуйте OWASP ZAP або Burp Suite для автоматичного сканування.
Ні, CORS не захищає від CSRF. CORS — механізм для безпечного читання крос-доменних відповідей, а CSRF-атаки не потребують читання відповіді — їм достатньо надіслати запит. CSRF-запити через <form> або <img> не підпадають під CORS-обмеження.
Якщо API використовує cookie-аутентифікацію — так, CSRF-захист обов'язковий. Якщо API працює з Bearer-токенами в заголовку Authorization, CSRF-ризик мінімальний, оскільки токени не відправляються автоматично браузером. Однак для гібридних додатків з WebView захист все одно рекомендується.
SameSite підтримується всіма сучасними браузерами з 2020 року. Для старих браузерів використовуйте CSRF-токени як основний метод захисту. Комбінація CSRF-токена + SameSite забезпечує максимальний захист навіть при вимкненому SameSite в legacy-браузерах.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також