solid / authentication-panel

GitHub repository for the Solid Authentication Panel
MIT License
11 stars 15 forks source link

Consider adding a 'nonce' param to WWW-Authenticate response header #3

Open dmitrizagidulin opened 5 years ago

dmitrizagidulin commented 5 years ago

As mentioned by @zenomt in https://github.com/solid/authentication-panel/issues/1, it may be advantageous to:

  1. Add a nonce param to the Resource Server's 401 WWW-Authenticate response headers.
  2. Require WebID-OIDC tokens (bearer or PoP) to include/pass through that nonce param, for verification by the RS

Specifically, on a 401 Unauthorized http response, the Resource Server would include the authenticate header that would look something like:

WWW-Authenticate: Bearer realm="..." scope="..." nonce="abcd123"

Opening this issue as a reminder to discuss:

zenomt commented 5 years ago

What to name that param (nonce or challenge or something else)

what to name it will depend on whether we keep the current POP token scheme or do something different (such as my proposal). a "nonce" should only be used once. if the challenge will be included in every POP token (and be verified that it was given by the RS), then it shouldn't be called a "nonce". something like challenge would be more appropriate for this use.

in my proposal, it's only used once when requesting the access token, so calling it nonce is appropriate.

zenomt commented 5 years ago

having a challenge in the POP token can also provide a reasonable way for the server to implement POP token revocation, by either forgetting the challenge from a table of valid ones, or (if #10 is implemented too) adding it to a table of revoked ones until it expires, which will be in a time determined to be reasonable to remember stuff for by the server.

elf-pavlik commented 4 years ago

I think UMA uses ticket for something similar as discussed here challenge

https://docs.kantarainitiative.org/uma/wg/rec-oauth-uma-grant-2.0.html#permission-success-to-client

If the resource server is able to provide a permission ticket from the authorization server, it responds to the client by providing a WWW-Authenticate header with the authentication scheme UMA, with the issuer URI from the authorization server's discovery document in an as_uri parameter and the permission ticket in a ticket parameter.

For example:

HTTP/1.1 401 Unauthorized
WWW-Authenticate: UMA realm="example",
as_uri="https://as.example.com",
ticket="016f84e8-f9b9-11e0-bd6f-0021cc6004de"
...
elf-pavlik commented 4 years ago

DPoP uses jti

jti: Unique identifier for the DPoP proof JWT (REQUIRED). The value MUST be assigned such that there is a negligible probability that the same value will be assigned to any other DPoP proof used in the same context during the time window of validity. Such uniqueness can be accomplished by encoding (base64url or any other suitable encoding) at least 96 bits of pseudorandom data or by using a version 4 UUID string according to [RFC4122]. The jti SHOULD be used by the server for replay detection and prevention, see (#Token_Replay).

I think it serves the same purpose as in cases where client creates nonce to prevent someone replying it requests. I still don't understand which threats nonce created by RS should address.

In UMA 2.0 we can find

permission ticket A correlation handle representing requested permissions that is created and maintained by the authorization server, initially passed to the client by the resource server, and presented by the client at the token endpoint and during requesting party redirects.

Which seems related to asynchronous claims gathering and need for some notion of transaction. I don't see exactly where we would have similar requirement in solid.

zenomt commented 4 years ago

an RS-chosen nonce forces the client to perform a cryptographic signature over a value that the RS has control over. there are multiple reasons this is important:

  1. the RS becomes an active, rather than passive, participant in the handshake
  2. the RS can be assured the nonce has a desired strength (can't be guessed, can't be forged)
  3. the RS can use the nonce for other purposes, such as correlating an original request with this response
  4. the RS can choose the nonce in such a way that it is easy and cheap (implementation-wise) for it to ensure it's only used once

any proof of possession should also use a client-chosen nonce (like jti) for the client to salt its signature.

elf-pavlik commented 4 years ago

@zenomt could you share an example of a threat which RS provided nonce mitigates?

zenomt commented 4 years ago

could you share an example of a threat which RS provided nonce mitigates?

the canonical threat is if a (large, possibly nation-state) adversary discovers a weakness in a cryptographic hash (for example, one used in a signature algorithm) that decreases the time to find a collision from essentially ∞ to, say, days-to-weeks-to-months.

if the time to find a collision is on the order of days or weeks or months, such an adversary could spend that time to forge a credential (like a POPToken) ahead of time to be used at just the right time to access a restricted resource.

a server-provided nonce reduces the amount of time an adversary has to find a collision from "unlimited" to the lifetime of the nonce, which should be on the order of minutes (EDIT and for a true single-use nonce, such as in my proposal: provided the nonce hasn't already been used/redeemed).

elf-pavlik commented 4 years ago

Thank you for clarifying @zenomt !

Looking at sequence diagram in https://github.com/zenomt/webid-auth-protocol#webid-oidc-proof-of-possession-operation

It looks that RS includes nonce in response which later client uses in request to webid_pop_endpoint. This looks similar to UMA2.0 where RS gets the ticket from AS before responding to client.

https://docs.kantarainitiative.org/uma/wg/rec-oauth-uma-grant-2.0.html#rs-tokenless-response

The resource server MUST obtain a permission ticket from the authorization server to provide in its response, but the means of doing so is outside the scope of this specification. For an example of how the resource server can obtain the permission ticket, see [UMAFedAuthz].

In cases like your proposal with webid_pop_endpoint and UMA2.0 using ticket seems straight forward. But in case where client directly presents credentials to RS I think it might not work that well. For example client would want to reuse same credentials for certain period of time, in that case one time use nonce wouldn't work and some challenge which client could use across multiple requests would require some wrapping of credentials and re-wrapping them once RS gives new challenge. If credentials have certain period between issuing them and expiring them, it already limits the time client can use them. As I understand we only talk about using that nonce between client and RS so it would not appear in credentials issued by the OP to the client, only in something client wraps them in to send to RS?

zenomt commented 4 years ago

As I understand we only talk about using that nonce between client and RS so it would not appear in credentials issued by the OP to the client, only in something client wraps them in to send to RS?

correct. as i mentioned above (https://github.com/solid/authentication-panel/issues/3#issuecomment-525073464 ) if this RS-provided challenge was going to be used in today's POPToken, it would more appropriately be called "challenge" because the expectation is it could be used more than once (until it expired or was revoked). calling it "nonce" is appropriate to my proposal because it's only used once.

zenomt commented 4 years ago

But in case where client directly presents credentials to RS I think it might not work that well.

a challenge can work fine in this case. however, for the multiple reasons i enumerated in #1 and #12, i think "client directly presents credentials to RS" is not ideal.