OAUTH 2.1 — новая эпоха безопасности
В последнее время всё чаще говорят об обновлении протокола аутентификации OAuth до версии 2.1. Но что на самом деле не так с текущей версией OAuth 2.0? Почему бы просто не продолжать использовать её? Этот вопрос активно обсуждают разработчики и команды, которые занимаются аутентификацией пользователей. Чтобы разобраться, что изменилось в новой версии, мы рассмотрим:
• В чём проблема OAuth 2.0?
• Почему обновление протокола важно для безопасности?
• Когда стоит задуматься о переходе на OAuth 2.1?
Эта статья поможет понять, почему назрела необходимость обновления протокола и когда вашей команде стоит начать планировать переход на новую версию.
Для начала расскажем о том, что такое Oauth и зачем он нужен.
OAuth (Open Authorization) — это открытый стандарт авторизации, который позволяет приложениям получать ограниченный доступ к данным пользователя на других сервисах без необходимости сообщать свои логин и пароль. Иными словами, мы можем зайти в любое приложение, введя данные для аутентификации только в приложении – поставщике аутентификации, а оно само взаимодействует с другими приложениями через передачу токенов.
В статье мы будем говорить о версии 2.0, потому что 1.0 устарела, хотя не исключаем, что кто-то до сих пор использует эту версию в своих приложениях.
В чём преимущество OAuth?
Если использовать приложения, которые специализируются на безопасности ввода данных, то можно быть уверенным в правильном шифровании, при котором злоумышленникам будет намного сложнее подобрать пароль от вашей учётной записи, а само приложение будет гарантировать доступ к другим сервисам с помощью токенов доступа.
Более того, Oauth прошёл огромное количество проверок временем, а его поведение и стандарты описаны в спецификациях, таким образом всё взаимодействие стандартизировано и разработчикам нет смысла каждый раз изобретать велосипед, а вместо этого можно использовать готовые решения, протестированные большим количеством пользователей.
Почему OAuth 2.0 стал популярным и нашёл отклик у разработчиков:
• Безопасное взаимодействие между сервисами: пользователь может разрешить приложению работать от его имени (например, читать почту или получать профиль).
• Универсальное взаимодействие: мобильные, веб- и серверные клиенты могут использовать один протокол.
• Гибкость: разные потоки аутентификации для разных типов клиентов.
Но даже при таком подходе появились уязвимости, которые необходимо закрыть для гарантированной безопасности продукта.
Почему OAuth 2.0 нуждается в обновлении?
OAuth 2.0 стал стандартом по умолчанию, но за годы его использования начали появляться уязвимости:
• использование Implicitly Flow, в котором токен доступа передаётся в открытом виде в URL;
• фишинг через подмену redirect_uri, если на стороне сервера авторизации не указывался полный путь до клиентского приложения;
• недостаточно генерируемых ошибок в обработке токенов доступа и обновления (access_token и refresh_token).
OAuth 2.0 — это не всегда про безопасность, несмотря на устоявшееся мнение.
Что такое OAuth 2.1?
OAuth 2.1 — эволюция без революции
OAuth 2.1 — это не новый протокол, а упрощённая и усиленная версия существующего OAuth 2.0. Он не ломает совместимость, требуя «всё переписать заново». Наоборот, он собирает лучшие практики и рекомендации, которые уже применяются в индустрии, делая базовый протокол:
• проще в реализации,
• безопаснее,
• понятнее для разработчиков.
Почему OAuth 2.1 стал проще?
• Удалены устаревшие и неоднозначные части спецификации:
— Поток Implicit Flow исключён, потому что он сложен в защите и больше не нужен (вместо него рекомендуется использовать Authorization Code с PKCE).
— Password Grant — исключён как небезопасный и нарушающий архитектурные принципы (передача логина и пароля напрямую клиенту).
• Уменьшено количество возможных вариантов реализации — стало меньше «если, но, может быть» в спецификации.
Почему безопаснее?
• PKCE (Proof Key for Code Exchange) стал обязательным — теперь даже публичные клиенты (мобильные и SPA) защищены от атак на авторизационный код.
• HTTPS теперь обязателен — все redirect-uri и авторизационные вызовы должны использовать защищённое соединение.
• Уточнены и ужесточены правила для refresh-токенов, client authentication и scope-ов по умолчанию.
Почему понятнее?
• Убраны противоречивые рекомендации из OAuth 2.0, заменены более чёткими и однозначными формулировками.
• Всё, что раньше приходилось искать в отдельных RFC (PKCE, Security Best Current Practices, рекомендациях OpenID Foundation), теперь собрано в одном месте.
• Разработчику проще понять: как правильно и безопасно реализовать поддержку протокола.
Статус: официально находится в статусе черновика, но уже поддерживается сообществом и крупными поставщиками (например, Keycloak в качестве дополнительного, а не обязательного к применению функционала).
Основные различия
Удалены устаревшие и небезопасные потоки:
● Implicit Flow — теперь запрещён.
Что это: раньше в браузерах токены могли передаваться прямо в URL (access_token в #fragment). Это было быстро и просто — но очень опасно.
В чём риск: любой скрипт на странице или реферер мог перехватить токен. Кроме того, токен нельзя было отозвать или обновить.
Что теперь: OAuth 2.1 полностью удаляет поддержку Implicit Flow, предлагая всем использовать более защищённый Authorization Code Flow с PKCE.
● Password Grant (ROPC) — тоже удалён.
Что это: клиент (например, мобильное приложение) напрямую просил у пользователя логин и пароль.
Проблема: нарушается разделение ответственности. Клиенту нельзя доверять обработку пароля — это задача Identity Provider-а.
Что теперь: ROPC официально исключён из спецификации. Остался только в случае строгой необходимости и контроля (например, в закрытых корпоративных системах — но даже там от него уходят).
«Передача логина и пароля клиенту — это как дать ключ от квартиры курьеру. Может пронесёт, а может — и нет.»
Обязательное использование PKCE
• Ранее PKCE применялся только для мобильных приложений.
• Теперь — обязателен для всех клиентов, даже конфиденциальных (например, web-backend).
• Что это: дополнительный защитный механизм, при котором клиент сначала создаёт код-верификатор и потом подтверждает его.
• Раньше: PKCE был рекомендован только для публичных клиентов.
• Теперь: PKCE обязателен для всех, включая конфиденциальные клиенты. Это защищает от атак с подменой кода (code injection, code replay).
«PKCE — это как двухфакторная авторизация внутри протокола. Даже если кто-то украдёт авторизационный код, без верификатора он ничего не сможет сделать.»
HTTPS — строго обязательно
• Теперь: все запросы, включая redirect_uri, должны использовать HTTPS.
• Почему это важно: передача токенов и кодов авторизации в незашифрованном HTTP — это как отправить пароль по открытке.
Улучшенное управление scope и refresh_token
• Теперь:
— Запрос без явного указания scope не должен по умолчанию получать чувствительные права.
— Требуется явное согласие пользователя (consent screen).
— Уточнены правила обработки prompt=none, max_age и других параметров авторизации.
• refresh_token теперь обязательно привязан к клиенту — снижается риск их повторного использования.
• Что нового:
— Refresh-токен должен быть привязан к клиенту.
— Рекомендуется привязывать его и к IP, и к User-Agent.
— Уточнены рекомендации по ротации и сроку жизни refresh-токен: Обязательная ротация при каждом использовании, Защита от повторного использования, Отклонять все токены из цепочки refresh token при обнаружении компрометации, Автоматический отзыв при смене пароля, логауте или подозрительной активности
Безопасность в OAuth 2.1
OAuth 2.1 закрывает важные уязвимости, включая:
• CSRF и перехват кода авторизации
• Подделку клиента (если client_id не проверяется строго)
• Replay-атаки
Рекомендации:
• Используйте PKCE + state.
• Проверяйте redirect_uri строго по exact match.
• Храните refresh_token безопасно (например, в httpOnly cookie).
Уязвимости, которые закрывает OAuth 2.1
1. CSRF и перехват кода авторизации
• Что это: злоумышленник может подменить запрос или перехватить код авторизации, если state не используется.
• Решение: теперь обязательным считается использование state (и даже nonce в OpenID Connect), чтобы сверять начало и конец потока.
• Вместе с PKCE это формирует мощную защиту от подделки и подмены.
2. Подделка клиента (client impersonation)
• Проблема: если не проводится строгая проверка redirect_uri, злоумышленник может использовать чужой client_id и отправить пользователя на свой redirect_uri, перехватив код.
• OAuth 2.1 требует:
— Точного совпадения redirect_uri (exact match, без wildcard и query-параметров).
— Привязку code_verifier (PKCE) к конкретному клиенту.
«У вас может быть идеальный client_id, но если redirect_uri не защищён — вы открыты для атак.»
3. Replay-атаки (повторное использование авторизационного кода)
• Сценарий: злоумышленник перехватывает авторизационный код и пытается использовать его второй раз.
• OAuth 2.1 решает это через:
— PKCE — без code_verifier украденный код бесполезен.
— Однократность использования кода (enforced).
— Ограниченное время жизни авторизационного кода.
«Даже если кто-то подслушал ваш код — без PKCE это просто шум.»
Рекомендации по безопасной реализации
Вот список обязательных практик, которые стоит внедрять — и которые OAuth 2.1 формализует как стандарт:
• Используйте PKCE + state — и сверяйте их при каждом обмене кодом.
• Проверяйте redirect_uri строго — вплоть до символа, без wildcard.
• Храните refresh_token безопасно — особенно в браузере: лучше всего в httpOnly cookie, чтобы JS не мог его прочитать.
• Применяйте ограниченные scope по умолчанию — и запрашивайте больше только при необходимости.
• Проверяйте client_id и привязывайте токены к нему.
Keycloak и OAuth 2.1
Если вы используете Keycloak, то с версии 25+:
• PKCE поддерживается по умолчанию для публичных клиентов.
• Проверка redirect_uri реализована строго.
• Ротация refresh_token и их привязка к клиенту включена.
• Дополнительные политики безопасности можно настраивать через Authentication Flows.
«Не нужно вручную собирать безопасность по кусочкам — современные провайдеры, такие как Keycloak, уже предоставляют всё это из коробки».
Заключение
OAuth 2.1 устраняет основные уязвимости OAuth 2.0, делая протокол безопаснее по умолчанию. Главные изменения — отказ от Implicit Flow и Password Grant, обязательный PKCE, HTTPS-only режим и усиленные refresh-токены. Разработчикам стоит начать переход уже сейчас, особенно в новых проектах.
Авторы:
Владимир Тютюнников, разработчик технологических платформ Банка ДОМ.РФ
Максим Беспалов, тимлид команды технологических платформ Банка ДОМ.РФ