Что такое интерцепция в OAuth

Authorization Code Interception Attack (атака перехвата кода авторизации) — это атака на OAuth 2.0 Authorization Code Flow, при которой злоумышленник перехватывает authorization_code на пути от сервера авторизации к клиентскому приложению и использует его для получения access_token вместо реального клиентского приложения.

Атака описана в спецификации RFC 7636 (Proof Key for Code Exchange, PKCE), где явно указано:

“OAuth 2.0 public clients utilizing the Authorization Code Grant are susceptible to the authorization code interception attack.”

Публичные клиенты OAuth 2.0, использующие предоставление кода авторизации, подвержены атаке перехвата кода авторизации. Вольный перевод

Ключевой момент: код авторизации — короткоживущий, но его этого времени достаточно, чтобы получить долгоживущий токен доступа. Именно поэтому перехват происходит в узком окне между получением кода и его обменом на токен.

Механика атаки

Стандартный Authorization Code Flow выглядит так: Стандартный Authorization Code Flow

При атаке интерцепции между шагами 2 и 3 появляется злоумышленник: Authorization Code Flow с интерцепцией

Условия для атаки:

  1. Клиент использует кастомную URI-схему (например, myapp://callback) — характерно для мобильных приложений.
  2. Несколько приложений могут зарегистрировать один и тот же URL в ОС — злоумышленник регистрирует своё приложение с той же схемой.
  3. ОС перенаправляет authorization_code в приложение злоумышленника.
  4. Злоумышленник первым получает authorization_code и, если не используется PKCE, успешно обменивает его на access_token. Легитимное приложение в лучшем случае не получает ничего, а в худшем — даже не подозревает об атаке, в то время как злоумышленник уже получил доступ к аккаунту пользователя.

Хотя базовый стандарт OAuth 2.0 RFC 6749 не предотвращает эту атаку, он формирует основу, на которую наслаиваются расширения безопасности. Главным из них является RFC 7636 (PKCE).

RFC 6749 и расширения Актуальные практики безопасности для OAuth 2.0 собраны в документе OAuth 2.0 Security Best Current Practice (BCP), который включает в себя RFC 9700 (самые свежие рекомендации на 2025 год) и обновлённый RFC 8252 (Best Practices for Native Apps).

Практические примеры

СредаРискПочему
Мобильные приложения (iOS/Android)🔴 ВысокийКастомные URI-схемы, несколько приложений могут их перехватить
SPA (Single Page Applications)🟠 СреднийНет возможности безопасно хранить client_secret. Код утекает через Browser History/Referer.
Desktop-приложения (Electron и др.)🟠 СреднийПохожая проблема с регистрацией URI-обработчиков
Публичные OAuth-клиенты🔴 ВысокийНе могут хранить client_secret
Конфиденциальные серверные клиенты🟢 НизкийЕсть client_secret, код без него бесполезен
Незащищённые Wi-Fi / VPN-сети🟠 СреднийMITM-атака при отсутствии TLS

Реальные векторы:

  • Вредоносное мобильное приложение, зарегистрировавшее тот же custom URI scheme, что и легитимное приложение банка или сервиса.
  • Поддельная VPN-утилита, запускающая MITM-прокси и перехватывающая /oauth/token запросы.
  • Клонированные веб-сайты с MITM-прокси на backend’е.
  • Злоупотребление встроенными OAuth-редиректами Microsoft/Google для фишинга (актуально в 2026 году).

Плюсы и минусы защиты через PKCE

PKCE (RFC 7636, произносится «пикси») — основная защита от интерцепции. Принцип работы:

  1. Клиент генерирует случайный code_verifier (43-128 символов)
  2. Вычисляет code_challenge = BASE64URL(SHA256(code_verifier))
  3. Отправляет code_challenge вместе с запросом авторизации
  4. Сервер сохраняет code_challenge
  5. При обмене кода на токен клиент присылает code_verifier
  6. Сервер проверяет: SHA256(code_verifier) == сохранённый code_challenge
  7. Только если совпадает — выдаёт access_token

Злоумышленник, перехвативший authorization_code, не знает оригинальный code_verifier — и не может получить токен.

Authorization Code Flow PKCE

Плюсы PKCE

  • Эффективно устраняет Authorization Code Interception Attack
  • Не требует client_secret — подходит для публичных клиентов (мобильные, SPA, desktop)
  • Рекомендован для всех типов клиентов — даже если есть client_secret (защищает от code injection)
  • Стандартизован — RFC 7636, поддерживается Auth0, Keycloak, Azure AD, Google, Okta и др.

Важный нюанс совместимости: Серверы, не поддерживающие PKCE, игнорируют параметры code_challenge и code_challenge_method. Это обеспечивает обратную совместимость, но не защищает канал. Защита работает только когда сервер требует PKCE.

Минусы и ограничения

  • Не является универсальной защитой — PKCE защищает именно процесс обмена кода на токен. Он не предотвращает утечку уже выданного access_token (например, через XSS или MITM после авторизации) и не решает проблему неправильной валидации redirect_uri.
  • Требует поддержки на сервере авторизации — если сервер не поддерживает PKCE и не требует его обязательно, защита не работает
  • Уязвим при использовании plain метода вместо S256plain не даёт криптографической защиты, рекомендуется всегда использовать S256
  • Не защищает от MITM при отсутствии TLS — PKCE предполагает, что TLS обеспечен
  • Не предотвращает replay-атаки на access_token — если токен украден после выдачи, PKCE уже не поможет

Инструменты: что используют атакующие и исследователи

Инструменты для перехвата и анализа

ИнструментНазначениеТип
mitmproxyHTTPS-перехватывающий прокси, позволяет перехватывать /oauth/token запросы и сохранять токеныOpen Source
Burp SuiteПрофессиональный инструмент для анализа веб-трафика, интегрируется с mitmproxy для тестирования OAuth-flowComm./Community
oauth-hunter (CyberArk)Специализированный инструмент на базе mitmproxy для перехвата и анализа OAuth-запросов, тестирует redirect_uri на уязвимостиOpen Source
mitmproxy JWT-refresh addonАддон для mitmproxy, автоматически перехватывает access_token и refresh_token, кеширует и подставляет в заголовкиOpen Source (gist)

Инструменты защиты и реализации PKCE

Инструмент / БиблиотекаЯзык / Платформа
AppAuth SDK (Google)iOS, Android, JS
MSAL (Microsoft).NET, JS, Python, Java
Auth0 SDKJS, Python, Go, Java и др.
KeycloakСервер авторизации с поддержкой PKCE
oauth2-proxyGo, универсальный reverse-proxy с PKCE

Пример: атака без PKCE vs. с PKCE

Без PKCE (уязвимо)

GET /authorize?
  response_type=code
  &client_id=myapp
  &redirect_uri=myapp://callback
  &scope=read

Сервер возвращает:

myapp://callback?code=AbCd1234

Если злоумышленник перехватил URI-редирект — код у него. Он делает:

POST /token
  grant_type=authorization_code
  &code=AbCd1234
  &client_id=myapp
  &redirect_uri=myapp://callback

==И получает access_token.==

С PKCE (защищено)

GET /authorize?
  response_type=code
  &client_id=myapp
  &redirect_uri=myapp://callback
  &scope=read
  &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
  &code_challenge_method=S256

Злоумышленник перехватывает code=AbCd1234. Пробует обменять:

POST /token
  grant_type=authorization_code
  &code=AbCd1234
  &client_id=myapp
  &redirect_uri=myapp://callback
  # code_verifier неизвестен!

Сервер отклоняет запрос: invalid_grant.

Дополнительные угрозы: не только Authorization Code

Интерцепция в OAuth — более широкое понятие. Помимо кода авторизации, атакующие перехватывают:

  • Access Token — через MITM, утечку из логов, XSS, скомпрометированное устройство. Защита: TLS, короткий TTL токена, scope-ограничения.
  • Refresh Token — долгоживущий, особенно ценен. Защита: ротация токенов (refresh_token_rotation), привязка к устройству.
  • Redirect URI manipulation — злоумышленник подменяет redirect_uri, чтобы код пришёл на его сервер. Защита: строгая валидация URI на сервере авторизации (не по prefix, а по точному совпадению).
  • Illicit Consent Grant (фишинг через OAuth) — злоупотребление доверием к платформам вроде Microsoft/Google. Пользователь перенаправляется на легитимный endpoint и авторизует вредоносное приложение, замаскированное под известный сервис (особо актуально в 2026 году).

Рекомендации

  1. Всегда используйте PKCE с методом S256 — для мобильных приложений, SPA и desktop-клиентов. С 2024 года рекомендован даже для конфиденциальных клиентов.
  2. Используйте state параметр для защиты от CSRF.
  3. Строго валидируйте redirect_uri — только точное совпадение, без path traversal и wildcard.
  4. Минимизируйте TTL токенов: access_token — 5–15 минут, refresh_token — с ротацией.
  5. Используйте универсальные ссылки (Universal Links / App Links) вместо кастомных URI-схем на мобильных платформах — они не могут быть перехвачены другим приложением.
  6. Храните code_verifier в sessionStorage, а не в localStorage — снижает риск XSS-атак.
  7. Обязательно TLS на всех endpoint’ах — PKCE не поможет при незащищённом транспорте.

Итог

Authorization Code Interception — не теоретическая угроза: она описана в основополагающих RFC, эксплуатируется в реальных атаках на мобильные и веб-приложения и является частью стандартных пентест-сценариев. PKCE (RFC 7636) — главное средство защиты, ставшее индустриальным стандартом. Главное правило: публичный клиент без PKCE = уязвимость.