Кратко

  • RFC 9207 даёт OAuth-клиенту узкую квитанцию: issuer в ответе авторизации должен точно совпасть с issuer, сохранённым для запроса. Несовпадение завершает поток до отправки кода на неправильный endpoint.
  • iss определяет контекст сервера авторизации. Поле не аутентифицирует пользователя, не проверяет код, не доказывает выпуск токена, его audience или scope и не говорит о решении resource server.
  • Проверяемая эксплуатация сохраняет отдельные записи о состоянии запроса, ожидаемом issuer, metadata, полученном issuer, сравнении, обмене кода, проверке токена, решении ресурса и восстановлении.

Опасный callback выглядит обычным.

Браузер возвращается на зарегистрированный redirect URI. state совпадает со значением клиента. Ответ несёт код, который выпустил честный сервер авторизации. Пароль не украден, код не подделан. И всё же клиент, работающий с несколькими серверами, способен совершить решающую ошибку маршрута: отправить этот настоящий код на token endpoint злоумышленника.

Проблема находится между двумя правдоподобными записями. Первая указывает сервер, который клиент считал выбранным при старте. Вторая — ответ авторизации, вернувшийся через браузер пользователя. Исходный ответ OAuth 2.0 не сообщал прямо, какой сервер его создал. Если общий callback или враждебные metadata сотрут границу, действительная credential перейдёт под контроль другого оператора.

RFC 9207 закрывает разрыв намеренно малым механизмом. OAuth 2.0 Authorization Server Issuer Identification, опубликованная в марте 2022 года как документ IETF Standards Track, — совместная работа Karsten Meyer zu Selhausen и Daniel Fett. Она определяет iss в ответе авторизации. Поддерживающий сервер включает свой issuer identifier и в успешный ответ, и в ошибку. Клиент сравнивает значение с issuer сервера, которому он отправил запрос.

Если строки различаются, клиент обязан отклонить ответ и не продолжать grant.

На этом полномочия поля заканчиваются. Именно поэтому оно полезно.

У callback не было имени отправителя

OAuth специально разделяет роли. Владелец ресурса использует user agent. Клиент запрашивает grant у сервера авторизации, затем предъявляет код token endpoint и позднее использует access token у resource server. Такая композиция соединяет независимые сервисы, но создаёт решения маршрута, которые не следуют из одного факта возвращения браузера.

RFC 6749 включила в ответ код и, если он был в запросе, тот же state. Состояние необходимо: оно связывает ответ с аутентифицированным состоянием браузера и помогает против CSRF. Но оно отвечает не на вопрос о том, какой сервер авторизации выпустил ответ.

При одном сервере различие может быть незаметно: другой связки endpoints нет. После добавления второго клиент должен помнить не только «ожидается OAuth-поток», но и кому этот поток принадлежит. RFC 9700, действующая Best Current Practice по безопасности OAuth, требует от multi-AS клиентов предотвращать mix-up и связывать ожидаемый issuer с каждым запросом.

Публичная работа Daniel Fett объясняет контекст, но не превращает коллективный стандарт в личный миф. Его сайт называет его консультантом по безопасности идентичности и веб-протоколов, работающим над OAuth и OpenID Connect. В сентябре 2026 года Datatracker перечислял у него четыре RFC, включая RFC 9207. Это связь тем, а не доказательство единоличного авторства или контроля над внедрением.

Один issuer указывает на связку endpoints

Issuer identifier — не отображаемое название. В RFC 8414 это HTTPS URL без query и fragment. Он якорит документ metadata, который может назвать authorization endpoint, token endpoint, местоположение ключей и другие возможности. Один host способен обслуживать несколько issuer с разными path.

Защищать нужно всю связку. Пользователь может видеть честную страницу авторизации, а конфигурация клиента соединит её с token endpoint злоумышленника. RFC 9700 предупреждает, что хранить только URL страницы недостаточно: атакующий может объявить честный authorization endpoint своим, но подставить собственный адрес обмена. Issuer стабильно идентифицирует комплект endpoints, который клиент собирался использовать.

RFC 9207 возвращает пришедший через браузер ответ к этому комплекту. При RFC 8414 значение iss должно быть идентично issuer из metadata, а сервер сообщает поддержку через authorization_response_iss_parameter_supported. Клиент извлекает значение, декодирует form encoding и выполняет простое строковое сравнение с ожидаемым issuer.

Приблизительного совпадения нет. Иной path, лишний slash или другой issuer на том же host — не «почти то же самое». Это не человеческое сравнение названий, а детерминированный маршрут.

Решение остаётся локальным. Сервер объявляет идентичность, metadata описывает связку, клиент хранит выбор и поддержку, сравнивает и прерывает. Общая спецификация даёт минимальный интерфейс, не забирая будущий выбор у оператора.

Совпадение разрешает следующий шаг, а не доказывает результат

Проще всего исказить iss, приписав ему лишнее.

Совпавший issuer не аутентифицирует владельца ресурса. Сервер ещё может потребовать вход или вернуть ошибку. Совпадение не доказывает понимание пользователем scope; это решение интерфейса авторизации и продуктовой политики.

Оно не валидирует код. Правильный token endpoint ещё проверяет код, клиентскую идентичность, redirect URI и другие условия. Код может истечь, быть повторённым или принадлежать другому клиенту.

Поле не доказывает выпуск токена. Тип, audience, scope, срок, sender constraint и отзыв остаются отдельными свойствами. Resource server решает при предъявлении. Даже валидный токен не доказывает успешное действие приложения и видимый пользователю результат.

Цепочка квитанций такова: создание запроса и сохранение issuer вместе с браузерным состоянием; прибытие ответа; значение iss; сравнение и принятие либо прерывание; выбор endpoints из проверенных metadata; принятие либо отказ кода; проверка токена и политика resource server; наблюдаемый итог и восстановление.

RFC 9207 отвечает за сравнение. Назвать его «успехом OAuth» — значит стереть все последующие решения.

Поле не является подписью

iss в обычном ответе не защищено криптографически. RFC 9207 говорит это прямо. Противоречие появляется только при попытке считать поле универсальным сертификатом.

Модель угрозы уже. При mix-up клиент получает ответ не скомпрометированного сервера, но путает связку endpoints для кода. Если злоумышленник способен изменить честный ответ до клиента, он уже может прочитать код и не нуждается в mix-up. Поле устраняет путаницу маршрута в этой модели, но не обещает целостность при любом противнике.

Где нужна защищённая целостность, issuer может передаваться внутри другого механизма. JARM помещает параметры в подписанный JWT. Некоторые потоки OpenID Connect возвращают ID Token с authorization endpoint и тоже несут issuer при правильной проверке. Несогласованные идентификаторы в одном ответе требуют отказа.

Это минимальная начальная спецификация в действии: добавить наименьший общий сигнал, открывающий неоднозначность, и оставить сильные оболочки, совместимость и миграцию локальному решению. RFC 9700 допускает и разные redirect URI для каждого issuer, если клиент их проверяет.

У старой совместимости должен быть владелец

Серверы обновляются не одновременно. Поэтому RFC 9207 хранит состояние поддержки по каждому серверу.

Если клиент знает о поддержке iss, отсутствие поля требует отказа. Для несовместимого сервера локальная политика может разрешить ответ или прекратить интеграцию. Неожиданное iss от сервера без объявленной поддержки тоже требует явного решения: это может быть drift конфигурации.

Гибкость определяет ответственность. Multi-issuer клиенту нужен реестр issuer, metadata, endpoints, источника и даты статуса поддержки, legacy-исключения, владельца и даты удаления. Без выхода «совместимость» становится постоянным обходным путём.

Добавление второго поставщика — изменение состояния безопасности. То, что защита была не нужна при одном issuer, ничего не говорит о расширенной системе. Привязка по запросу должна попасть в работающий код до запуска.

Квитанция, которую может проверить эксплуатация

Одно чтение metadata не доказывает внедрение. Испытание начинается при создании запроса.

Записываются ID, user-agent binding, выбранный issuer, версия metadata, endpoints, support flag и redirect URI. После возврата — наличие и декодированное значение iss, ожидаемое значение, результат сравнения и фактическое подавление обмена кода. Нужны успех и ошибка, отсутствие и дубликат, неизвестный issuer и два path одного host.

Решающим остаётся отрицательный тест. После несовпадения ни один запрос с кодом, client credential или token не должен дойти до неожиданного endpoint. Логи клиента и контролируемых тестовых серверов должны совпасть. Видимая ошибка при отправленном сетевом запросе — не защита.

В расследовании mismatch доказывает провал сравнения, но не обязательно компрометацию. Отказ token endpoint доказывает отказ одному grant, а не враждебность ответа. Отказ resource server не подтверждает задним числом корректную issuer binding.

Поле работает, когда превращает скрытую неоднозначность в обязательное решение до перемещения секрета. Оно называет сервер. Токен и результат по-прежнему требуют собственных доказательств.

Источники