Subject: [OAUTH-WG] draft-ietf-oauth-dpop-00 comments

From: "Peck, Michael A" <[email-masked]>
Date: Wed, 1 Apr 2020 17:13:45 +0000

Hi,

Glad to see DPoP moving forward as a working group item.
I have a couple of comments on the current draft:

1.
I recommend expanding the description of the threat model.
It's not entirely clear to me what threats DPoP is expected to address, which makes it hard to evaluate whether DPoP meets its objectives.

Section 2 states that the main objective is to prevent an adversary who set up a counterfeit AS or RS from replaying a received refresh token or access token at another server. Would it be possible to expand upon the description of this threat and how it may occur?
Are there other situations where an adversary may be able to capture a refresh token or access token that should be mentioned as objectives to address - e.g. malicious / third-party JavaScript code?

Presumably the counterfeit AS or RS will not have the same hostname (e.g. with an illegitimately issued server certificate) as the legitimate server, as otherwise DPoP wouldn’t provide protection. Why would the client send the refresh token to the wrong AS?

For resource servers, why wouldn’t an access token audience restriction suffice? Is the concern that the access token might not contain an audience restriction, or might contain multiple audiences? (If the concern is that the resource server wouldn’t check the audience, I’d have a similar concern that it wouldn’t check a DPoP proof.)

2.
DPoP currently does not provide any guarantees that the DPoP signature was freshly generated, as there is no nonce from the server incorporated into the signature.
I assume there is no practical means for the server to send a nonce to the client to use with each request that wouldn't over-complicate DPoP.
I also don't see any guidance in the draft about lifetime/rotation of each DPoP key or whether the same key can be used with multiple servers.

My concern is that something analogous to this Kerberos PKINIT attack - https://mailarchive.ietf.org/arch/msg/krb-wg/pLgID35fNG1Zh_QJjgXH9vEbwoQ/ - could occur if DPoP signatures can be pre-computed by an adversary that somehow gains the ability to compute signatures with the private key but doesn't gain access to the private key itself. Could that potentially happen with malicious JavaScript code?

The iat timestamp is insufficient since future values could be inputted with the signatures stored for later use. I could envision a private key potentially being re-used for a long period of time, and depending on how DPoP ends up getting used in practice, a private key being used with multiple servers?

If guaranteeing some degree of freshness of the signature is a concern, one solution could be to incorporate the authorization code into the DPoP signature for token requests to the AS with grant_type=authorization_code, incorporate the refresh token into the DPoP signature for token requests to the AS with grant_type=refresh_token, and incorporate the access token into the DPoP signature for requests to a resource server. That would prevent pre-computing DPoP signatures before the authorization code / refresh token / access token is generated by the AS, as long as the recipient properly checks the DPoP proof.

I'd also suggest adding guidance on rotating the DPoP key - e.g. mandate/recommend that the client create a new keypair for each token request?

Thanks,
Mike

---

From: Brian Campbell <[email-masked]>
Date: Mon, 6 Apr 2020 12:05:28 -0600

Hi Mike,

Thanks for your interest in the work and review of the draft. As one of the
too-many authors on the document, I attempt to answer questions and respond
to comments inline below. Though I admit to not having necessarily adequate
answers to everything at the ready. And also apologize for the slow
response, which is somewhat related to not having necessarily adequate
answers.

On Wed, Apr 1, 2020 at 11:15 AM Peck, Michael A <[email-masked]> wrote:

> It's not entirely clear to me what threats DPoP is expected to address,
> which makes it hard to evaluate whether DPoP meets its objectives.
>

Yeah, there's definitely some room for improvement in this area. And you
are not the first to note the need. Complicating matters somewhat, however,
is that there's some disparity of opinions about the specifics of the
threat model and objectives. Despite that I do plan to work on trying to
expand and clarify the threat model, objectives, expected applicability,
etc. in the next revision of the draft.

> Section 2 states that the main objective is to prevent an adversary who
> set up a counterfeit AS or RS from replaying a received refresh token or
> access token at another server. Would it be possible to expand upon the
> description of this threat and how it may occur?
>

I'm hoping perhaps Daniel can help expand on this as the current text
originated with him. Although I think separate consideration of AS and RS
would be helpful because I think the factors involved in counterfeiting or
confusing them are pretty different.

> Are there other situations where an adversary may be able to capture a
> refresh token or access token that should be mentioned as objectives to
> address - e.g. malicious / third-party JavaScript code?
>

Probably, yeah. Although any JavaScript code that could exfiltrate tokens
could also likely be used to drive an attack directly. And that possibility
can devolve into questioning the value of key-binding or preventing
exfiltration at all (similarish criticisms have been levied at the HttpOnly
cookie flag and HTTP Token Binding). I'm sympathetic to that line of
reasoning to the point of finding it somewhat depressing. But I try and
avoid falling into full-blown XSS nihilism and (maybe stubbornly/naively)
still think there's some value in key constraining tokens. And, to your
point, a more detailed look at potential leakage/theft situations would be
useful.

>
> Presumably the counterfeit AS or RS will not have the same hostname (e.g.
> with an illegitimately issued server certificate) as the legitimate server,
> as otherwise DPoP wouldn’t provide protection.

Yeah, an assumption (that admittedly should be made more explicit) is that
TLS/HTTPS with server authentication isn't broken.

> Why would the client send the refresh token to the wrong AS?
>

 Daniel maybe has some more ideas here but social engineering is the one
reason that I keep hearing. It's not super compelling but is a reason.

> For resource servers, why wouldn’t an access token audience restriction
> suffice? Is the concern that the access token might not contain an audience
> restriction, or might contain multiple audiences? (If the concern is that
> the resource server wouldn’t check the audience, I’d have a similar concern
> that it wouldn’t check a DPoP proof.)
>

Audience restriction can work to prevent RS to RS token usage. But in
practice it has turned out that properly getting and using audience
restricted ATs is prohibitively cumbersome for many deployments.

>
> 2.
> DPoP currently does not provide any guarantees that the DPoP signature was
> freshly generated, as there is no nonce from the server incorporated into
> the signature.
> I assume there is no practical means for the server to send a nonce to the
> client to use with each request that wouldn't over-complicate DPoP.
>

Keeping it relatively simple has definitely been a goal. And yeah, I can't
think of a practical way to do something like that without big changes. If
big changes are needed, the whole approach might be in question and
something like Neil's key agreement scheme that I mentioned in the last
interim
https://datatracker.ietf.org/meeting/interim-2020-oauth-02/session/oauth
could well be a better overall approach to consider.

> I also don't see any guidance in the draft about lifetime/rotation of each
> DPoP key or whether the same key can be used with multiple servers.
>

Some guidance would probably be useful.

>
> My concern is that something analogous to this Kerberos PKINIT attack -
> https://mailarchive.ietf.org/arch/msg/krb-wg/pLgID35fNG1Zh_QJjgXH9vEbwoQ/
> - could occur if DPoP signatures can be pre-computed by an adversary that
> somehow gains the ability to compute signatures with the private key but
> doesn't gain access to the private key itself. Could that potentially
> happen with malicious JavaScript code?
>

Trying to wrap my head around this and how it might happen but yes it would
seem that the kind of malicious JavaScript code (like XSS) that could
exfiltrate tokens or drive an attack directly could also pre-compute and
exfiltrate some DPoP proofs. I hadn't considered this and am honestly not
sure how problematic it is.

>
> The iat timestamp is insufficient since future values could be inputted
> with the signatures stored for later use. I could envision a private key
> potentially being re-used for a long period of time, and depending on how
> DPoP ends up getting used in practice, a private key being used with
> multiple servers?
>
> If guaranteeing some degree of freshness of the signature is a concern,
> one solution could be to incorporate the authorization code into the DPoP
> signature for token requests to the AS with grant_type=authorization_code,
> incorporate the refresh token into the DPoP signature for token requests to
> the AS with grant_type=refresh_token, and incorporate the access token into
> the DPoP signature for requests to a resource server. That would prevent
> pre-computing DPoP signatures before the authorization code / refresh token
> / access token is generated by the AS, as long as the recipient properly
> checks the DPoP proof.
>

That's an interesting consideration and along the lines (at least with
authorization code) of some of the conversations we had early on before the
first -00 draft was even written. And I've noticed that other signature
based proof concepts do typically propose having the signature cover the
access token (or hash thereof). Personally, I've gotten kind of attached to
the simplicity and consistency in the current draft of having the DPoP
proof be the same regardless of where it's presented. And I kind of cringe
at having to dig into the application layer to get at an authorization code
or refresh token value in order to verify the DPoP proof. Also considering
other grant types. So I don't want to move away from that too hastily.

But I suppose it depends on how much of a concern it is to ensure some
degree of freshness. And weighing that against the potential added
complexity of doing something like the above to try and get freshness. I'm
honestly not sure where I sit on it.

>
> I'd also suggest adding guidance on rotating the DPoP key - e.g.
> mandate/recommend that the client create a new keypair for each token
> request?
>

A recommendation like that (new keypair per token request and subsequent
access token usage) probably makes sense. I think. In the case of a bound
refresh token issued to a public client, the lifetime of the keypair would
need to correlate with the refresh token (unless facilities are added to
enable dpop key rotation in that scenario).

>
> Thanks,
> Mike
>
>
> _______________________________________________
> OAuth mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/oauth
>

-- 
_CONFIDENTIALITY NOTICE: This email may contain confidential and privileged 
material for the sole use of the intended recipient(s). Any review, use, 
distribution or disclosure by others is strictly prohibited.  If you have 
received this communication in error, please notify the sender immediately 
by e-mail and delete the message and any file attachments from your 
computer. Thank you._

---

From: Justin Richer <[email-masked]>
Date: Mon, 6 Apr 2020 17:37:03 -0400

I want to add my perspective to the question of audience restriction, below:

One of the problems with implementing audience restriction of RS’s in the wild has actually turned into a problem of audience identification instead. In other words, the client needs to know some identifier that the RS will recognize as itself, and the RS needs to be configured with that identifier in some way. DPoP does a nice side-step of that entire issue by signing some very limited aspects of the request itself. This type of check is much easier for an RS (or a filter sitting in front of it) to check for consistency, without a lot of pre-configuration. The http-signing based PoP draft took the same approach, albeit with more expanded coverage, and the HTTP Signatures draft from the HTTP WG will do the same. 

I’ll also note that this does not get in the way of DPoP being used with an access token that also has additional audience restrictions on it. And RS can both check the DPoP signature matches the incoming request as well as checking some audience notation on the token itself, just like we’d expect an RS to check the scope values bound to the access token as well as the presentation mechanism. 

They’re two parts of the puzzle, and they shouldn’t be conflated at the presentation layer (DPoP) since they can be mixed in orthogonal ways for different use cases and solutions.

 — Justin

> On Apr 6, 2020, at 2:05 PM, Brian Campbell <bcampbell=[email-masked]> wrote:
> 
> Hi Mike,
> 
> Thanks for your interest in the work and review of the draft. As one of the too-many authors on the document, I attempt to answer questions and respond to comments inline below. Though I admit to not having necessarily adequate answers to everything at the ready. And also apologize for the slow response, which is somewhat related to not having necessarily adequate answers. 
> 
> On Wed, Apr 1, 2020 at 11:15 AM Peck, Michael A <[email-masked] <mailto:[email-masked]>> wrote:
> Hi,
> 
> Yeah, there's definitely some room for improvement in this area. And you are not the first to note the need. Complicating matters somewhat, however, is that there's some disparity of opinions about the specifics of the threat model and objectives. Despite that I do plan to work on trying to expand and clarify the threat model, objectives, expected applicability, etc. in the next revision of the draft. 
>  
> I'm hoping perhaps Daniel can help expand on this as the current text originated with him. Although I think separate consideration of AS and RS would be helpful because I think the factors involved in counterfeiting or confusing them are pretty different.
>  
> Probably, yeah. Although any JavaScript code that could exfiltrate tokens could also likely be used to drive an attack directly. And that possibility can devolve into questioning the value of key-binding or preventing exfiltration at all (similarish criticisms have been levied at the HttpOnly cookie flag and HTTP Token Binding). I'm sympathetic to that line of reasoning to the point of finding it somewhat depressing. But I try and avoid falling into full-blown XSS nihilism and (maybe stubbornly/naively) still think there's some value in key constraining tokens. And, to your point, a more detailed look at potential leakage/theft situations would be useful.
> 
>  
> 
> Presumably the counterfeit AS or RS will not have the same hostname (e.g. with an illegitimately issued server certificate) as the legitimate server, as otherwise DPoP wouldn’t provide protection.
> 
> Yeah, an assumption (that admittedly should be made more explicit) is that TLS/HTTPS with server authentication isn't broken.  
> 
>  
>  Daniel maybe has some more ideas here but social engineering is the one reason that I keep hearing. It's not super compelling but is a reason.
> 
>  
> Audience restriction can work to prevent RS to RS token usage. But in practice it has turned out that properly getting and using audience restricted ATs is prohibitively cumbersome for many deployments. 
>  
> 
> 2.
> Keeping it relatively simple has definitely been a goal. And yeah, I can't think of a practical way to do something like that without big changes. If big changes are needed, the whole approach might be in question and something like Neil's key agreement scheme that I mentioned in the last interim https://datatracker.ietf.org/meeting/interim-2020-oauth-02/session/oauth <https://datatracker.ietf.org/meeting/interim-2020-oauth-02/session/oauth> could well be a better overall approach to consider. 
>  
> My concern is that something analogous to this Kerberos PKINIT attack - https://mailarchive.ietf.org/arch/msg/krb-wg/pLgID35fNG1Zh_QJjgXH9vEbwoQ/ <https://mailarchive.ietf.org/arch/msg/krb-wg/pLgID35fNG1Zh_QJjgXH9vEbwoQ/> - could occur if DPoP signatures can be pre-computed by an adversary that somehow gains the ability to compute signatures with the private key but doesn't gain access to the private key itself. Could that potentially happen with malicious JavaScript code?
> 
> Trying to wrap my head around this and how it might happen but yes it would seem that the kind of malicious JavaScript code (like XSS) that could exfiltrate tokens or drive an attack directly could also pre-compute and exfiltrate some DPoP proofs. I hadn't considered this and am honestly not sure how problematic it is.
>  
> 
> That's an interesting consideration and along the lines (at least with authorization code) of some of the conversations we had early on before the first -00 draft was even written. And I've noticed that other signature based proof concepts do typically propose having the signature cover the access token (or hash thereof). Personally, I've gotten kind of attached to the simplicity and consistency in the current draft of having the DPoP proof be the same regardless of where it's presented. And I kind of cringe at having to dig into the application layer to get at an authorization code or refresh token value in order to verify the DPoP proof. Also considering other grant types. So I don't want to move away from that too hastily. 
> 
> But I suppose it depends on how much of a concern it is to ensure some degree of freshness. And weighing that against the potential added complexity of doing something like the above to try and get freshness. I'm honestly not sure where I sit on it.  
>  
> 
> A recommendation like that (new keypair per token request and subsequent access token usage) probably makes sense. I think. In the case of a bound refresh token issued to a public client, the lifetime of the keypair would need to correlate with the refresh token (unless facilities are added to enable dpop key rotation in that scenario). 
>  
> 
> Thanks,
> Mike
> 
> 
> [email-masked] <mailto:[email-masked]>
> https://www.ietf.org/mailman/listinfo/oauth <https://www.ietf.org/mailman/listinfo/oauth>
> 
> CONFIDENTIALITY NOTICE: This email may contain confidential and privileged material for the sole use of the intended recipient(s). Any review, use, distribution or disclosure by others is strictly prohibited..  If you have received this communication in error, please notify the sender immediately by e-mail and delete the message and any file attachments from your computer. Thank you._______________________________________________
> OAuth mailing list
> [email-masked]

---

From: Benjamin Kaduk <[email-masked]>
Date: Mon, 6 Apr 2020 20:54:22 -0700

> point, a more detailed look at potential leakage/theft situations would be

One point to consider is whether the exfiltrated material can be widely
replicated to turn into a distributed attack.

> sure how problematic it is.

There should be plenty of ways to include a server contribution into the
DPoP proof (e.g., a TLS exporter value).
> honestly not sure where I sit on it.

I think I've forgotten some of the context here, but will note that in
general at IESG evaluation time we end up asking whether there are more
parameters that make sense to be covered by the signature/proof/etc.

-Ben

---

From: Brian Campbell <[email-masked]>
Date: Tue, 7 Apr 2020 15:31:09 -0600

One of the primary motivations for the proof-of-possession mechanism of
DPoP being at the application layer was to hopefully enable implementation
and deployment by regular application developers. A lesson learned from the
difficulties and lack of adoption around Token Binding was that access to
TLS exporters is non-existent or prohibitively cumbersome in many
development environments. Browsers, for example, don't expose any such API
to javascript. And that's a non-starter here.

Are there other practical ways to include a server contribution that have
been overlooked?

---

From: Benjamin Kaduk <[email-masked]>
Date: Tue, 7 Apr 2020 21:51:18 -0700

> Are there other practical ways to include a server contribution that have

the main thing that comes to mind is (basically) an explicti nonce, which
costs an extra round trip unless you get clever.

In particular, "get clever" can be something that amortizes a single extra
round trip across *all* interactions with that server, akin to how ACME
requires a fresh nonce (and signature) for each request (RFC 8555).

-Ben