redirect_uri in url query vs request object

Issue #128 resolved
Joseph Heenan created an issue

FAPI part 1 says "shall require the redirect_uri parameter in the authorization request;".

It's not 100% clear to me what this means.

OpenBanking appear to have interpreted it as meaning "the redirect_uri must be present in the url query". OpenBanking also require the redirect_uri to be within the request object. The core specs clearly say that if both are present the request object one overrides the url query one.

I think we should be clearer; I am thinking that if the redirect_uri is present in the request object it should NOT be in the url query. Having the uri is two places just seems unnecessary and potentially result in the AS using the wrong one in some paths.

Comments (17)

  1. Joseph Heenan reporter

    Here's an example from the OB specs:

    GET /authorize?
    response_type=code id_token
    &client_id=s6BhdRkqt3
    &state=af0ifjsldkj
    &scope=openid accounts
    &nonce=n-0S6_WzA2Mj
    &redirect_uri=https://api.mytpp.com/cb
    &request=CJleHAiOjE0OTUxOTk1ODd.....JjVqsDuushgpwp0E.5leGFtcGxlI
    iwianRpIjoiM....JleHAiOjE0.olnx_YKAm2J1rbpOP8wGhi1BDNHJjVqsDuushgpwp0E
    

    where the request object is:

    {
        "alg": "RS256",
        "kid": "GxlIiwianVqsDuushgjE0OTUxOTk"
    }
    .
    {
       "iss": "https://api.alphabank.com",
       "aud": "s6BhdRkqt3",
       "response_type": "code id_token",
       "client_id": "s6BhdRkqt3",
       "redirect_uri": "https://api.mytpp.com/cb",
       "scope": "openid payments accounts",
       "state": "af0ifjsldkj",
       "nonce": "n-0S6_WzA2Mj",
       "max_age": 86400,
       "claims":
        {
         "userinfo":
          {
           "openbanking_intent_id": {"value": "urn:alphabank:intent:88379", "essential": true}
          },
         "id_token":
          {
           "openbanking_intent_id": {"value": "urn:alphabank:intent:88379", "essential": true},
           "acr": {"essential": true,
                    "values": ["urn:openbanking:psd2:sca",
                         "urn:openbanking:psd2:ca"]}}
          }
        }
    }
    .
    <<signature>>
    
  2. Freddi Gyara

    Joseph,

    The example there is non-normative.

    We do not have a requirement around the disposition of the redirect_uri - it could be a query parameter or in the request object (or indeed, both - in which case the request object prevails).

    We did subscribe to the FAPI requirement that the redirect_uri must be specified.

  3. John Bradley

    OAuth currently requires the redirect_URI be sent as a query paramater. The Connect spec can't change OAuth only profile it. That is why the one in the request object overrides the one in the paramater but can't replace it.

    Obviously that is not ideal, and you are correct that ideally it should only be sent one place.

    In the OAuth version of JWT signed request https://tools.ietf.org/html/draft-ietf-oauth-jwsreq-15

    Given that it is a OAuth spec and updates OAuth we were able to remove the requirement for duplicate parameters. Unfortunately, while that spec is finished WG last call it is hung up in the IESG process at IETF and is not yet a RFC.

    So based o current Connect specs the redirect_uri parameter is required, that could and should change in the future once the OAuth spec is approved.

    From a practical point of view, I think a number of OAuth servers expect to see the parameter and may break if it is not present.

    John B.

  4. Joseph Heenan reporter

    Thank you John, that's very helpful.

    Is there something in FAPI or the parent specs that requires that the redirect_uri is present in the request object? If not it sounds like we could sensibly add that requirement to FAPI?

    Am I correct in thinking that, in the case where the redirect_uri is present in the request object, any differing redirect_uri in the query parameter must still be one registered to the client?

    (The latter question is asked from the point of view of how a conformance suite might verify correct behaviour in this case.)

  5. Nat Sakimura
    • changed status to open

    So, this means that request_uri has to be in Authorization Request in one way or another. For Part 1, it could just be a parameter. For Part 2, it has to be in the request object (otherwise it will defeat the purpose of protecting the request.) It could be in the parameter as well but must be ignored.

  6. Nat Sakimura

    One question. Why just request_uri? The direction of OAuth JAR is that everything MUST BE in the request object, including state. It removes the cacheability optimization, but the IETF security review prevailed that the security benefit overrides the cacheability. If we take that direction, then we should mandate everything to be in the request object and that was the intention when drafting Part 2.

  7. Joseph Heenan reporter

    @Nat I was wondering about raising another ticket about everything else.

    Thanks for the info about the IETF security review, I agree that in case it makes sense to protect everything. I've updated my pull request with a new suggested wording.

  8. Nat Sakimura

    Part 2: Require parameters to be inside signed request object

    fixes #128 (or at least fixes the only part it seems we can currently fix without violating the underlying specifications)

    This should help mitigate any attacks that require changing the redirect_uri etc.

    The redirect_uri appears to still be required as a parameter outside the request object for compliance with the current underlying OAuth RFC (although my personal opinion is that this is not clearly stated in the specifications). response_type, scope and client_id must be included as parameters outside the request object.

    The OIDC Core spec is already clear on behaviour in the case where these fields are present in both location:

    "When the request parameter is used, the OpenID Connect request parameter values contained in the JWT supersede those passed using the OAuth 2.0 request syntax."

    → <<cset 92c6b808f206>>

  9. Log in to comment