Re: [OAUTH-WG] Benjamin Kaduk's Yes on draft-ietf-oauth-par-08: (with COMMENT)

Benjamin Kaduk <kaduk@mit.edu> Thu, 01 July 2021 01:48 UTC

Return-Path: <kaduk@mit.edu>
X-Original-To: oauth@ietfa.amsl.com
Delivered-To: oauth@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id 060833A0BD6; Wed, 30 Jun 2021 18:48:14 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -4.197
X-Spam-Level:
X-Spam-Status: No, score=-4.197 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, SPF_HELO_NONE=0.001, SPF_NONE=0.001, URIBL_BLOCKED=0.001] autolearn=ham autolearn_force=no
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id BxXu2fVnqMAJ; Wed, 30 Jun 2021 18:48:08 -0700 (PDT)
Received: from outgoing.mit.edu (outgoing-auth-1.mit.edu [18.9.28.11]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id 49B123A0BD4; Wed, 30 Jun 2021 18:48:07 -0700 (PDT)
Received: from mit.edu ([24.16.140.251]) (authenticated bits=56) (User authenticated as kaduk@ATHENA.MIT.EDU) by outgoing.mit.edu (8.14.7/8.12.4) with ESMTP id 1611lwh9013165 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 30 Jun 2021 21:48:02 -0400
Date: Wed, 30 Jun 2021 18:47:57 -0700
From: Benjamin Kaduk <kaduk@mit.edu>
To: Brian Campbell <bcampbell@pingidentity.com>
Cc: The IESG <iesg@ietf.org>, draft-ietf-oauth-par@ietf.org, oauth-chairs@ietf.org, oauth <oauth@ietf.org>, Hannes Tschofenig <hannes.tschofenig@arm.com>
Message-ID: <20210701014757.GM17170@mit.edu>
References: <162490954694.18608.7401442671159157596@ietfa.amsl.com> <CA+k3eCQ0pta9G2Rqy-p+Bi3aFgBu89EKKNeyqPg+qBH4JiN-aA@mail.gmail.com>
MIME-Version: 1.0
Content-Type: text/plain; charset="us-ascii"
Content-Disposition: inline
In-Reply-To: <CA+k3eCQ0pta9G2Rqy-p+Bi3aFgBu89EKKNeyqPg+qBH4JiN-aA@mail.gmail.com>
Archived-At: <https://mailarchive.ietf.org/arch/msg/oauth/09LiuSqGsObBMgJZWlQejKOgIsM>
Subject: Re: [OAUTH-WG] Benjamin Kaduk's Yes on draft-ietf-oauth-par-08: (with COMMENT)
X-BeenThere: oauth@ietf.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: OAUTH WG <oauth.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/oauth>, <mailto:oauth-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/oauth/>
List-Post: <mailto:oauth@ietf.org>
List-Help: <mailto:oauth-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/oauth>, <mailto:oauth-request@ietf.org?subject=subscribe>
X-List-Received-Date: Thu, 01 Jul 2021 01:48:14 -0000

Hi Brian,

On Wed, Jun 30, 2021 at 01:10:37PM -0600, Brian Campbell wrote:
> Thanks Ben, I've endeavored to respond to your comments inline below. And I
> will/am working on related document updates but have some time off planned
> around the 4th of July so likely won't have a new revision out until next
> week sometime.

Understandable!

> On Mon, Jun 28, 2021 at 1:45 PM Benjamin Kaduk via Datatracker <
> noreply@ietf.org> wrote:
> 
> > Benjamin Kaduk has entered the following ballot position for
> > draft-ietf-oauth-par-08: Yes
> >
> > The document, along with other ballot positions, can be found here:
> > https://datatracker.ietf.org/doc/draft-ietf-oauth-par/
> >
> >
> > ----------------------------------------------------------------------
> > COMMENT:
> > ----------------------------------------------------------------------
> >
> > I made a github PR with some editorial suggestions, at
> > https://github.com/oauthstuff/draft-oauth-par/pull/70 .
> >
> 
> Merged on Monday. Thank you.
> 
> 
> Section 1
> >
> >                                        Those apps typically invoke a
> >    custom tab with an URL that is translated into a GET request.  Using
> >    "POST" would require the app to first open a web page under its
> >    control in the custom tab that in turn would initiate the form "POST"
> >    towards the authorization server.  PAR is simpler to use and has
> >    additional security benefits as described above.
> >
> > This description leaves me with a feeling that I only have an incomplete
> > picture of why POST is "prohibitively difficult" to use with mobile
> > apps.  It seems like the setup is describing a scenario where the
> > authorization logic is operating inside a framework or environment
> > provided by some other entity that is unwilling or unable to change the
> > framework to accomodate new OAuth behavior.  Is this other entity the
> > author of the mobile app, or an app framework, or somethint else?
> > Having a bit more description of the multiple entities involved and
> > which one is trying to control the specific mechanics of the
> > authorization request would make this depiction a more compelling
> > argument that POST is unusable.
> >
> 
> I think perhaps myself and co-authors are so familiar with it that it seems
> almost self-evident. This is the second ballot comment on this paragraph,
> however, so it seems some more work on the text is warranted. I'll try to
> elaborate and better explain why it isn't particularly viable for a native
> mobile app to cause the user's browser on the device to make a POST request
> (with sizable body content).

I think that even mentioning that there are ecosystem pressures to use the
native (OS?) browser for an otherwise independent app (that acts as OAuth
client) would be helpful.  The fact that the interface between native apps
and the system browser has limitations should be fairly easy to accept as a
fact of life, whereas the current text invites the reader to ask "but can't
you just make a POST request yourself?  Why is that so hard?".

> 
> 
> 
> > Section 1.1
> >
> >      POST /as/par HTTP/1.1
> >      Host: as.example.com
> >      Content-Type: application/x-www-form-urlencoded
> >      Authorization: Basic czZCaGRSa3F0Mzo3RmpmcDBaQnIxS3REUmJuZlZkbUl3
> >
> > My personal preference would be to have examples that just want a
> > generic HTTP authentication mechanism to use something stronger than
> > Basic, though I don't think this is something that I can insist on, at
> > present.  (Applies throughout.)
> >
> 
> I wavered on this very point when putting together the examples but
> eventually took the easy route and went with Basic (aka
> client_secret_basic). The three such examples just want to show some form
> of OAuth client authentication happening. I think JWT based client
> assertion authentication using asymmetric keys
> https://datatracker.ietf.org/doc/html/rfc7523#section-2.2 (aka
> private_key_jwt) is the only stronger mechanism that would show well in
> examples (MTLS/RFC8705 is hard to show in a meaningful way in an HTTP
> example). I could update the examples to use RFC7523
> client_assertion/client_assertion_type parameter auth?

That would address my concern, but I understand that it's a nontrivial
amount of work and definitely am not insisting on it.

> 
> 
> 
> >      HTTP/1.1 201 Created
> >      Cache-Control: no-cache, no-store
> >      Content-Type: application/json
> >
> >      {
> >        "request_uri": "urn:example:bwc4JK-ESC0w8acc191e-Y1LTC2",
> >        "expires_in": 90
> >      }
> >
> > The "request_uri" element's semantics feels like a very natural fit for
> > the native HTTP "Location" response header field (vs requiring a
> > specific element in the JSON body of the response).  I am less sure that
> > there's a native HTTP element for the expiration time, as the HTTP
> > timeouts tend to be associated with HTTP caching vs the actual lifetime
> > of the resource.
> >
> 
> The semantics feel subtly different in that the "request_uri" value is not
> used as-is by the client but rather as a query string parameter in the
> construction of the full authorization request URI to which it will direct
> the user's browser. I was also unsure whether the "Location" response
> header field had to have a resolvable URI value (I didn't find text saying
> so explicitly but it seems somewhat logical). Also, to me anyway, it made
> sense and was more consistent to keep the OAuth parameters at the same
> layer they show up in other OAuth exchanges. And, as you note, there isn't
> an obvious HTTP field to convey the expiration time and putting some
> protocol data in the headers and some in the JSON content payload seemed
> awkward.
> 
> That's some of the reasoning behind not using the "Location" header.
> Avoiding a breaking change at this stage is another reason.

Indeed.  And to be honest, the last one is pretty compelling.
(I am not an HTTP expert and should not opine on whether the Location
response value has to be resolvable or not.  I do think that "the location
of the resource that was created" is a good fit even if the resource itself
is not accessed directly by the entity that receives the HTTP response with
the location header field -- a URI is a way to identify a resource, after
all, and that identifier can be passed around to other entities.)

> 
> 
> > Section 2
> >
> > It feels a little unfortunate that we have to reuse the metadata
> > parameters relating to the token_endpoint_auth_method for PAR, but
> > creating new metadata parameters that are basically always going to hold
> > the same values is probably worse...
> >
> 
> I believe the reuse is exactly what's wanted here. The unfortunate part is
> in the naming that, in retrospect, is overly specific.

Er, yes, exactly that.

> Section 2.1
> >
> >                     Any token endpoint parameters that are not related
> >    to client authentication have no defined meaning for a pushed
> >    authorization request.  [...]
> >
> > I suppose that in most cases, whether or not a token endpoint parameter
> > is related to client authentication should be fairly unambiguous ... but
> > the registry at
> >
> > https://www.iana.org/assignments/oauth-parameters/oauth-parameters.xhtml#parameters
> > has a dedicated column for "parameter usage location".  It seems like it
> > would be fairly straightforward to add "pushed authorization request" as
> > an additional possible value there and remove the ambiguity.  We could
> > enumerate the existing parameters that are applicable and update the
> > references for the registry to include this document.
> >
> 
> I believe the text describes the situation pretty well and resolves the
> ambiguities sufficient for interoperable implementations/deployments in
> practice. A registry update is possible but would be a significant change
> with ongoing maintenance needs that aren't readily apparent while not
> providing practical value.

I won't insist on anything; the benefit would mostly be "ideological
cleanliness" which is not very tangible.

> 
> 
> > Section 2.1
> >
> >    The authorization server MUST process the request as follows:
> >
> > We often see descriptions along the lines of "this is not intended to
> > constrain implementation techniques; any procedure that results in an
> > equivalent outcome is permissible".  This procedure is simple enough
> > that we may not need to have concerns of that nature, though.
> >
> > Section 2.2
> >
> >    *  "request_uri" : The request URI corresponding to the authorization
> >       request posted.  This URI is used as reference to the respective
> >       request data in the subsequent authorization request only.  [...]
> >
> > Would it be appropriate to use the phrase "single-use" in this
> > description?
> >
> 
> Yes, I think so. I'll add it.
> 
> 
> 
> > Section 2.4
> >
> >    It is at the discretion of the authorization server to apply
> >    restrictions on supplied "redirect_uri" values, e.g. the
> >    authorization server MAY require a certain URI prefix or allow only a
> >    query parameter to vary at runtime.
> >
> > Is this expected to be discoverable by the client?  Would there be a
> > particular error code used, for example?
> >
> 
> It's not so much intended to be discoverable but more to just note the
> possible exception to the tightening restrictions on redirect_uri values in
> the security BCP and OAuth 2.1. It's allowance/utilization will likely be
> determined for a whole deployment or ecosystem, which will also dictate the
> specific URI allowances and how clients are configured or registered with
> such info.

Okay.

> 
> Section 3
> >
> >                                    When the "application/x-www-form-
> >    urlencoded" HTTP entity-body "request" parameter is used, the request
> >    object MUST contain all the authorization request parameters as
> >    claims of the JWT.  Additional request parameters as required by the
> >    given client authentication method are to be included as
> >    'application/x-www-form-urlencoded' parameters in the HTTP request
> >    entity-body [...]
> >
> > I might flip this around and start off with "authentication request
> > parameters required by a given client authentication method are included
> > in the application/x-www-form-urlencoded request directly, and are the
> > only parameters other than 'request' in the form body.  All other
> > request parameters, i.e., those pertaining to the authorization request
> > itself, MUST appear as claims of the JWT representing the authorization
> > request".  The current formulation kind of hides the specifics of how to
> > determine which parameter goes where -- the spec for the client
> > authentication method in use is the authoritative one, IIUC.
> >
> 
> That makes sense, I'll flip it around like you suggest (modulo a few
> wording tweaks).
> 
> 
> 
> >    1.  If applicable, decrypt the request object as specified in JAR
> >        [I-D.ietf-oauth-jwsreq], section 6.1.
> >
> >    2.  Validate the request object signature as specified in JAR
> >        [I-D.ietf-oauth-jwsreq], section 6.2.
> >
> > Do we want to say anything more about error handling if decryption or
> > signature validation fails?
> >
> 
> The referenced sections in JAR indicate "invalid_request_object" as the
> error code, which seems sufficient and doesn't warrant repeating here.

Okay, makes sense.

> 
> Section 4
> >
> > I think we should explicitly state that expired "request_uri"s are
> > rejected as invalid.
> >
> 
> Sure, I can add that.
> 
> 
> Section 5
> >
> >    Note that the presence of "pushed_authorization_request_endpoint" is
> >    sufficient for a client to determine that it may use the pushed
> >    authorization request flow.  A "request_uri" value obtained from the
> >    PAR endpoint is usable at the authorization endpoint regardless of
> >    other authorization server metadata such as
> >    "request_uri_parameter_supported" or
> >    "require_request_uri_registration".
> >
> > Since this is the only mention of it in this document, and it's an OIDC
> > parameter, maybe we should provide a reference for
> > "require_request_uri_registration"?
> >
> 
> Sure, I'll add an informational reference to
> https://openid.net/specs/openid-connect-discovery-1_0.html
> 
> 
> 
> > Section 7.1
> >
> >    An attacker could attempt to guess and replay a valid request URI
> >    value and try to impersonate the respective client.  [...]
> >
> > Just to confirm my analysis here: an attacker that does guess a valid
> > request URI value would probably also need to guess the corresponding
> > "client_id", and if the request used PKCE, would also need to guess the
> > PKCE value in order to successfully obtain a token response?  I'm not
> > sure whether any of that is worth mentioning or not here, though.
> >
> 
>  While true, it's immaterial when the URI value itself is not guessable. So
> I don't think it needs mentioning.

Okay.

> 
> 
> > Section 10.3
> >
> > Section 12
> >
> > Why is RFC 6749 not a normative reference?
> >
> 
> Just a mistake due to a tooling misunderstanding - see the reply to the
> same issue raised by Zaheduzzaman Sarker
> https://mailarchive.ietf.org/arch/msg/oauth/Mx_6jDnlE4vjn4UvywNJ5QV4Y_M/
> 
> 
> NITS
> >
> > Section 2
> >
> >    The pushed authorization request endpoint is an HTTP API at the
> >    authorization server that accepts HTTP "POST" requests with
> >    parameters in the HTTP request entity-body using the "application/x-
> >    www-form-urlencoded" format with a character encoding of UTF-8 as
> >
> > I'm not sure where "entity-body" is defined as the name for the request
> > body in this case; draft-ietf-httpbis-semantics would seem to just have
> > us refer to this as the "message body".
> >
> 
> Sure, I'll change it and the few other occurrences to "message body" (FWIW
> I think "entity-body" came from text borrowed from RFC 6749, which in turn
> used the term from RFC 2616).
> 
> 
> Section 2.1
> >
> >    The client adds the parameters in "x-www-form-urlencoded" format with
> >
> > I'd suggest a different word than "adds"; these paratmers are the entire
> > body, not appended to some earlier structure.
> >
> 
>  Okay. Maybe "constructs the request with parameters" or similar ...
> 
> > Some parameters of the example request (e.g., "state") are duplicated
> > across the multiple examples in the document.  For those which are
> > typically single-use in practice, we might consider using different
> > values in the different examples (including in the JWT payload of the
> > example request in Section 3).
> >
> 
> The JWT payload of the example request in Section 3 was kinda sorta meant
> to show what the same request from an earlier example in 2.1 would look
> like in JWT request form. So I might keep that. But in general the

If you do, please note that it's intended to match up!

> suggestion makes sense and I'll take a pass through the examples to try and
> ensure things that should be unique are unique.

Thanks!

> Section 7.4
> >
> > The section heading is "Client Policy Change", which to me indicates a
> > change in the policy of the client, that is, what the client requires.
> > The text of the section indicates that this is discussing the AS's
> > per-client policy, though, so I wonder if there is a better phrasing
> > that could be used.
> >
> 
>  Maybe configuration rather than policy? I dunno. I'm tempted to just
> remove 7.4

I'd prefer leaving it alone over removing it, if we can't find any wordings
that we like better than what's there.

Thanks for all the responses and updates!

-Ben