Skip to content

Name the issuer in authorization responses (RFC 9207) - #283

Merged
longsleep merged 1 commit into
libregraph:masterfrom
longsleep-io:upstream/7-rfc9207-iss
Oct 14, 2026
Merged

longsleep merged 1 commit into
libregraph:masterfrom
longsleep-io:upstream/7-rfc9207-iss

Conversation

@longsleep

Copy link
Copy Markdown
Collaborator

A client which talks to several authorization servers cannot tell from a bare code and state which server answered. A malicious server can then get it to send a code issued by an honest server to the attacker's token endpoint: the mix-up attack of RFC 9207 section 1. RFC 9207 closes this by having the authorization server name itself in every authorization response.

Changes

  • Every authorization response redirected to the client carries iss, the issuer exactly as in the discovery document. This covers successes and errors, in the query and in the fragment.
  • The metadata announces authorization_response_iss_parameter_supported: true. Section 2.3 ties the flag to the parameter. Under section 2.4, a client which sees the flag rejects a response without iss or with a different one, by simple string comparison.
  • Errors get iss in NewError and NewBadRequest of AuthenticationRequest. Every error redirected to a client is built there: denied consent, required login or interaction, invalid_target, converted OAuth2 errors. So no call site changes.
  • Error bodies rendered as JSON don't carry iss. Logout redirects aren't authorization responses and stay without it. HTML error pages are unchanged.

Clients which don't know RFC 9207 ignore the extra parameter, as RFC 6749 section 4.1.2 requires for unrecognized response parameters.

Tests and docs

  • The new TestAuthorizeResponseIss checks the metadata flag, and that a success redirect and an error redirect carry iss equal to the discovery issuer. It fails without the change.
  • Tested with a locally built licod: the metadata announces the flag, and an error redirect for an unknown resource carries iss.
  • The API spec and the README list RFC 9207. The spec also describes iss on the authorize endpoint and the metadata field.

A client talking to several authorization servers cannot tell from a
bare code and state which server answered. A malicious server can then
get it to send a code issued by an honest one to the attacker's token
endpoint, the mix-up attack of RFC 9207 section 1. RFC 9207 lets the
authorization server name itself in every response with iss, and
section 2.4 makes a client which sees the metadata announce support
reject a response without iss or with a different one, by simple
string comparison.

Every authorization response redirected to the client, success and
error alike, now carries iss, the issuer identifier exactly as in the
discovery document, and the metadata announces
authorization_response_iss_parameter_supported: true, as RFC 9207
section 2.3 ties the two together.

AuthenticationSuccess gains Iss, set in AuthorizeResponse from the
provider's issuer identifier. AuthenticationError and
AuthenticationBadRequest gain Iss for the URL only, tagged json "-",
since they are also rendered as JSON bodies where iss has no place. It
is filled in NewError and NewBadRequest of AuthenticationRequest from
the provider metadata the request already holds. Every error
redirected to a client goes through these two constructors, from the
identity managers, denied consent, required login or interaction,
invalid_target and the OAuth2Error conversion, so no call site
changes. Logout redirects, which also use AuthenticationSuccess, are
not authorization responses and stay without iss. HTML error pages are
unchanged. Clients which do not know RFC 9207 ignore the extra
parameter, as RFC 6749 section 4.1.2 requires of unrecognized response
parameters.

The API spec lists RFC 9207 in its info section, describes iss for the
authorize endpoint and its error convention and gains the metadata
field, and the README lists RFC 9207 among the standards.

The new TestAuthorizeResponseIss checks that the metadata announces
support and that both a success redirect and an error redirect, an
invalid_target for an unregistered resource, carry iss equal to the
discovery issuer. It fails without the change. The helper
getTestProviderMetadata fetches the discovery document for it.

Verified live, the built licod announces the flag, and an error
redirect for an unknown resource carries error=invalid_target, its
description and state, and iss=https%3A%2F%2Flocalhost%3A18781.
@longsleep
longsleep merged commit 410f69d into libregraph:master Oct 14, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant