CSRF в мобильной разработке: суть, типы атак и методы защиты

Автор: IT Sectr Опубликовано: 2026-04-06 Время чтения: 9 мин

CSRF (Cross-Site Request Forgery) — тип атаки, при которой злоумышленник заставляет браузер жертвы отправить поддельный запрос на целевой сервер от имени авторизованного пользователя. По данным OWASP, 2026, CSRF входит в десятку наиболее критичных рисков для веб-приложений. В контексте мобильной разработки CSRF-атаки особенно опасны для REST API, использующих cookie-аутентификацию. Межсайтовая подделка запроса остаётся актуальной угрозой, несмотря на внедрение современных защитных механизмов.

Главное

  • CSRF — атака, эксплуатирующая доверие сервера к браузеру авторизованного пользователя
  • Основная цель — выполнение действий от имени жертвы без её согласия: перевод средств, смена пароля, удаление данных
  • Cookie-аутентификация — главный вектор: браузер автоматически прикрепляет куки к запросам, и сервер не отличает легитимный запрос от поддельного
  • CSRF-токены — основной метод защиты: уникальный секретный токен проверяется на сервере перед выполнением операции
  • SameSite — атрибут cookie, ограничивающий отправку куки при кросс-доменных запросах, значительно снижает риск CSRF

Что такое CSRF-атака?

CSRF (Cross-Site Request Forgery) — это атака, при которой злоумышленник создаёт поддельный запрос и заставляет браузер жертвы отправить его на целевой сервер. Сервер выполняет запрос, поскольку получает валидные cookie-credentials текущей сессии пользователя. Атака возможна потому, что браузер автоматически добавляет куки к каждому запросу на целевой домен, независимо от того, с какой страницы отправлен запрос. Пользователь мог даже не видеть страницу злоумышленника — достаточно загрузить скрытый <img>, <form> или <iframe> с вредоносным URL. CSRF не крадёт данные напрямую — атака выполняет действия от имени жертвы (state-changing operations), такие как перевод денег, изменение пароля или удаление аккаунта.

Какие операции наиболее уязвимы?

CSRF-атаки направлены исключительно на операции, изменяющие состояние — GET-запросы с побочными эффектами, POST, PUT и DELETE. Например, запрос на смену email-адреса в личном кабинете: если сервер принимает запрос без проверки происхождения, злоумышленник может подставить свою почту и инициировать сброс пароля. Атака особенно опасна для банковских систем, панелей администратора и социальных сетей, где одно действие влечёт серьёзные последствия. API мобильных приложений, использующие куки для аутентификации, также подвержены CSRF, если не применяют дополнительные проверки.

Кто в зоне риска?

Под атаку попадают любые веб-приложения и API, где аутентификация основана на cookie, а сервер не проверяет происхождение запроса. Мобильные приложения, использующие WebView для авторизации через веб-формы, также уязвимы: браузерный компонент автоматически отправляет куки, и злоумышленник может внедрить вредоносный запрос через фоновую загрузку. По данным HackerOne (2025), около 12% всех отчётов об уязвимостях в веб-приложениях связаны с отсутствием защиты от CSRF.

Что делает CSRF опасным?

Главная особенность CSRF — незаметность для жертвы. Пользователь может даже не подозревать, что атака произошла: поддельный запрос выполняется в фоновом режиме, а интерфейс приложения не показывает признаков взлома. Единственный способ обнаружить CSRF — мониторинг серверных логов или внезапные изменения в аккаунте. Кроме того, CSRF легко комбинируется с другими уязвимостями, такими как XSS или открытые редиректы, что многократно усиливает ущерб.

Как работает CSRF-атака?

CSRF-атака состоит из трёх обязательных условий: жертва авторизована на целевом сайте, сервер использует cookie-аутентификацию, а запрос злоумышленника направлен на action-URL. Злоумышленник создаёт HTML-страницу с формой, скриптом или изображением, чей атрибут src указывает на целевой URL. Браузер жертвы загружает эту страницу и автоматически отправляет запрос на сервер вместе с cookie текущей сессии. Сервер получает валидные куки, не проверяет источник запроса и выполняет операцию.

html
<!-- Пример 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. Сервер банка проверяет куки, убеждается, что пользователь аутентифицирован, и выполняет перевод на счёт злоумышленника. Жертва видит пустую или легитимную страницу, а деньги уже списаны.

Роль браузера в CSRF

Ключевая особенность протокола HTTP — отсутствие встроенной проверки источника запроса. Браузер добавляет куки к запросу, если домен запроса совпадает с доменом куки. Злоумышленнику не нужно знать содержимое куки — браузер делает это автоматически. Same-origin policy не защищает от CSRF, поскольку атака направлена на сервер, а не на чтение ответа. Механизмы вроде CORS также бессильны: CSRF-запросы обычно не требуют чтения ответа, чтобы нанести ущерб.

Основные типы CSRF-атак

CSRF-атаки классифицируются по способу доставки вредоносного запроса. Каждый тип использует разный HTML-элемент для отправки запроса, но все полагаются на автоматическую отправку cookie браузером. Выбор метода зависит от целей атакующего: GET-based атаки требуют меньше кода, POST-based надёжнее обходят некоторые защиты, а XMLHttpRequest-based позволяют манипулировать заголовками.

Тип атакиВектор доставкиHTTP-методСложность обнаружения
GET-based<img>, <script>, <iframe>GETВысокая
POST-basedСкрытая <form> + автоподачаPOSTСредняя
XHR-basedXMLHttpRequest с CORSЛюбойНизкая

GET-based CSRF

Самый простой метод: злоумышленник помещает на страницу <img> с URL, содержащим параметры запроса. Браузер загружает изображение и отправляет GET-запрос на сервер. Например, <img src="https://api.example.com/delete?postId=123" /> удаляет запись, если сервер обрабатывает DELETE через GET. Несмотря на очевидную опасность, некоторые API до сих пор используют GET для операций удаления или обновления.

POST-based CSRF

Если сервер принимает только POST-запросы, злоумышленник создаёт скрытую форму с методом POST и автоматически отправляет её через JavaScript. Форма не отображается на экране (все <input> имеют type="hidden"), а autofocus + .submit() срабатывает без клика пользователя. POST-based атаки не работают, если сервер проверяет заголовок Content-Type, но большинство API принимают стандартный application/x-www-form-urlencoded.

XHR-based CSRF (с CORS)

XMLHttpRequest или Fetch API позволяют отправлять запросы с произвольными заголовками. Если сервер настроил CORS слишком широко (Access-Control-Allow-Origin: *), злоумышленник может отправить любой запрос и прочитать ответ. Однако для CSRF-атаки чтение ответа не обязательно — достаточно выполнить действие. Современные браузеры отправляют preflight-запрос OPTIONS перед нестандартными запросами, что может заблокировать XHR-based CSRF, если сервер правильно настроен.

CSRF в мобильных приложениях

Мобильные приложения уязвимы к CSRF в меньшей степени, чем веб-сайты, поскольку нативные приложения редко используют cookie-аутентификацию. Вместо этого мобильные API чаще применяют токены в заголовке Authorization (Bearer-токены, JWT). Однако есть сценарии, где CSRF-атака возможна: WebView с веб-логином, гибридные приложения и API с cookie-based сессиями. По данным TechCrunch (2025), порядка 18% публичных API мобильных приложений всё ещё поддерживают сессионные куки.

CSRF через WebView

Многие приложения открывают веб-страницы в WebView — авторизацию через OAuth, платёжные формы, просмотр контента. WebView — это полноценный браузер внутри приложения, который хранит сессионные куки. Если злоумышленник находит способ загрузить свой URL в WebView (через открытый редирект или Deep Link), он может выполнить CSRF-атаку точно так же, как в обычном браузере. Защита — использование Chrome Custom Tabs или SFSafariViewController вместо WebView для критических операций.

CSRF в API с JWT-аутентификацией

JWT-токены обычно хранятся в localStorage или в памяти приложения и не отправляются автоматически — разработчик явно добавляет заголовок Authorization к каждому запросу. Это делает классическую CSRF-атаку невозможной. Однако если приложение хранит JWT в cookie (что редкость, но встречается), риск возвращается. Дополнительная защита — привязка JWT к конкретному origin запроса через claim azp или aud, что предотвращает использование токена на другом домене.

javascript
// Пример серверной проверки 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 строится на трёх уровнях: серверные CSRF-токены, атрибут SameSite для cookie и проверка заголовка Origin. Комбинация этих методов обеспечивает защиту от 99% CSRF-атак без существенного влияния на UX. Выбор конкретного подхода зависит от архитектуры приложения: веб-сайту достаточно SameSite=Lax, API мобильного приложения требует токенов в заголовках.

CSRF-токены (синхронизатор)

Стандартный метод: сервер генерирует уникальный токен, привязывает его к сессии пользователя и передаёт клиенту. Клиент включает токен в каждый запрос, изменяющий состояние (в скрытом поле формы или заголовке X-CSRF-Token). Сервер сверяет полученный токен с хранящимся в сессии. Токен должен быть криптостойким, случайным, длиной не менее 32 байт, и меняться при каждой сессии или операции. Срок жизни токена — не более нескольких часов.

SameSite Cookie

Атрибут SameSite для куки ограничивает отправку куки при кросс-доменных запросах. Значение Lax разрешает отправку куки только для навигационных GET-запросов верхнего уровня — этого достаточно для большинства сайтов. Strict блокирует куки для всех кросс-доменных запросов, включая навигацию: пользователю придётся заново авторизоваться при переходе с другого сайта. По данным Chrome Platform Status (2026), SameSite=Lax по умолчанию включён во всех современных браузерах, что снизило количество CSRF-атак на 67%.

Проверка Origin и Referer

Сервер может проверять заголовки Origin или Referer входящего запроса. Если запрос пришёл с другого домена — он блокируется. Origin надёжнее Referer, так как всегда присутствует в POST-запросах и не отключается политиками браузера. Реализация: белый список разрешённых origins, сравнение с текущим значением заголовка. Метод эффективен, но сложен с мобильными приложениями, где заголовки Origin могут отсутствовать или подделываться.

kotlin
// Пример проверки 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()
    }
}

Double Submit Cookie

Метод, не требующий хранения токена на сервере: сервер устанавливает cookie с случайным значением, клиент читает значение из cookie и отправляет его обратно в заголовке или теле запроса. Сервер сравнивает оба значения. Если злоумышленник не может читать cookie (Same-origin policy), он не сможет подделать токен. Метод проще в реализации, чем синхронизатор, но требует HTTPS для защиты cookie от перехвата.

  • CSRF-токены — золотой стандарт: надёжны, проверены временем, поддерживаются всеми фреймворками
  • SameSite=Lax — минимальная защита для веб-приложений: бесплатно, автоматически, не требует кода
  • Проверка Origin — дополнительный уровень: блокирует атаки до проверки токена
  • Double Submit — для REST API без server-side сессий: эффективен на HTTPS
  • Кастомные заголовки — X-Requested-With: XMLHttpRequest блокирует простые CSRF-формы

Различие между CSRF и XSS

CSRF и XSS — разные типы атак, которые часто путают. CSRF эксплуатирует доверие сервера к браузеру пользователя: сервер выполняет команду злоумышленника, потому что запрос приходит с валидными куки. XSS эксплуатирует доверие браузера к контенту сервера: браузер выполняет скрипт, встроенный злоумышленником в страницу. CSRF не требует внедрения кода на целевом сайте — достаточно отправить запрос с другого домена. XSS, напротив, требует найти способ внедрить свой JavaScript в HTML-код страницы. При этом XSS может обходить CSRF-защиту: внедрённый скрипт читает CSRF-токен со страницы и отправляет его вместе с запросом.

ХарактеристикаCSRFXSS
Цель атакиСерверКлиент (браузер)
ВекторПодделка запросаВнедрение скрипта
Нужен JavaScript на сайте жертвы?НетДа
Кража данныхНет (только действия)Да
ЗащитаCSRF-токен, SameSite, OriginЭкранирование вывода, CSP

Понимание разницы между CSRF и XSS критически важно для построения многоуровневой защиты. CSRF-токены не защищают от XSS, а CSP (Content Security Policy) не защищает от CSRF. Только комбинация методов обеспечивает безопасность приложения от обоих типов атак. В мобильных приложениях с WebView риски удваиваются, поэтому разработчикам рекомендуется применять как минимум CSRF-токены для API-запросов и Content Security Policy для веб-контента.

Часто задаваемые вопросы

Чем CSRF отличается от межсайтового скриптинга?

CSRF вынуждает сервер выполнить действие от имени пользователя, а XSS внедряет вредоносный скрипт в браузер жертвы. CSRF не требует внедрения кода на целевом сайте — достаточно отправить запрос с другого домена. XSS, в отличие от CSRF, может красть данные и читать содержимое страницы.

Как узнать, уязвимо ли моё приложение к CSRF?

Проверьте, используете ли вы cookie-аутентификацию и есть ли проверка происхождения запроса для state-changing операций. Если API принимает POST/PUT/DELETE без CSRF-токена, проверки Origin или SameSite — приложение уязвимо. Используйте OWASP ZAP или Burp Suite для автоматического сканирования.

Защищает ли CORS от CSRF?

Нет, CORS не защищает от CSRF. CORS — механизм для безопасного чтения кросс-доменных ответов, а CSRF-атаки не требуют чтения ответа — им достаточно отправить запрос. CSRF-запросы через <form> или <img> не подпадают под CORS-ограничения.

Нужна ли CSRF-защита для REST API мобильного приложения?

Если API использует cookie-аутентификацию — да, CSRF-защита обязательна. Если API работает с Bearer-токенами в заголовке Authorization, CSRF-риск минимален, поскольку токены не отправляются автоматически браузером. Однако для гибридных приложений с WebView защита всё равно рекомендуется.

Что делать, если SameSite не поддерживается браузером?

SameSite поддерживается всеми современными браузерами с 2020 года. Для старых браузеров используйте CSRF-токены как основной метод защиты. Комбинация CSRF-токена + SameSite обеспечивает максимальную защиту даже при отключённом SameSite в legacy-браузерах.

Итоги

  • CSRF — атака подделкой межсайтового запроса, эксплуатирующая доверие сервера к браузеру авторизованного пользователя
  • Механизм атаки — браузер автоматически отправляет куки с запросом, сервер не отличает легитимный запрос от поддельного
  • Основные типы — GET-based (через <img>), POST-based (через скрытую форму), XHR-based (через CORS)
  • Мобильная специфика — WebView и cookie-аутентификация в гибридных приложениях создают CSRF-риски
  • CSRF-токены — самый надёжный метод защиты, поддерживаемый всеми фреймворками
  • SameSite=Lax — автоматическая защита на уровне браузера, включена по умолчанию
  • Комбинированная защита — токены + SameSite + проверка Origin обеспечивают защиту от 99% CSRF-атак

Мы разработаем мобильное приложение под ключ

IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.

Обсудить проект

Читайте также