Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

substantial and significant security issues with current "bearer token" scheme #1

Closed
zenomt opened this issue Aug 11, 2019 · 15 comments
Labels
can-be-closed? This issue is slated to be closed

Comments

@zenomt
Copy link
Contributor

zenomt commented Aug 11, 2019

as i mentioned on the mailing list on july 12, i believe there are substantial and significant security issues with the currently implemented (with documentation waiting to be merged) Proof-of-Possession "bearer token" authorization scheme. the most important issues are:

  • the client creates and issues "bearer tokens" with no input from the resource server (or its authorization infrastructure). in general, the client has no standing in the OAuth model to create or issue an access token. this is incompatible with the kinds of OAuth infrastructure likely to be deployed in enterprises.
  • there’s no reasonable way for the resource server (or its authorization infrastructure) to revoke one of these tokens.
  • the validity period (nbf, exp) is solely under control of the webid’s OIDC Issuer and the client/app, another aspect over which those parties don’t have standing. the resource+authorization server is the only party with standing to specify the validity period of its access tokens, which might be shorter or longer than the validity period in any identity proof provided by the client.
  • the format of the bearer token is mandated, rather than being up to the resource and authorization servers. this makes it potentially incompatible (or at least non-optimal) with the kinds of OAuth infrastructure likely to be deployed in enterprises.
  • there’s no provision for multiple protection spaces (realms) with different security policies at the same origin.
  • there’s no way for the resource server to force a current/timely proof of possession of the confirmation key.
  • (related) there’s no way for the resource server to directly cryptographically challenge the client (for example, with a salt/nonce).

also, these proof tokens are necessarily big and must be passed around on every request. HTTP/2 header compression might mitigate that somewhat over the network between a client and a server (or at least a reverse proxy or application gateway), but at some point in the processing chain a multi-K blob of bytes needs to be processed on every request.

some time ago i proposed an alternative authorization method that addresses the above concerns.

@dmitrizagidulin
Copy link
Member

dmitrizagidulin commented Aug 12, 2019

Hi @zenomt! Thanks for bringing up these issues; these are all excellent discussion points.

Couple of comments to clarify.

the client creates and issues "bearer tokens" with no input from the resource server (or its authorization infrastructure).

That's correct. Specifically, the client (RP/presenter) issues signed PoP tokens for each resource server. The resource server has only two inputs at the moment (as reflected in the WWW-Authenticate response headers on 401s):

Sample 401 header: WWW-Authenticate: Bearer realm="https://solid.community", scope="openid webid"

  1. The RS's origin dictates the audience of the token
  2. The scope param indicates which auth protocol the RS is running (openid webid === WebID-OIDC, in this case -- see issue Decide on header/mechanism for reporting auth metadata for a Solid pod (RS) #4 for discussion).

(related) there’s no way for the resource server to directly cryptographically challenge the client (for example, with a salt/nonce).

True, we don't use a challenge or nonce in the 401 responses currently. That's definitely something we can add (and require the PoP tokens to include). (Opened new issue, #3)

there’s no reasonable way for the resource server (or its authorization infrastructure) to revoke one of these tokens.
the validity period (nbf, exp) is solely under control of the webid’s OIDC Issuer and the client/app, another aspect over which those parties don’t have standing.

Not quite the case. The RS can revoke a token simply by refusing to honor it, for whatever reason. So, the Resource Server (Solid at the moment has no concept of a RS+Authorization server pair, the only Authorization Server in play is the IdP) has full control over the tokens.

the format of the bearer token is mandated, rather than being up to the resource and authorization servers

That's correct. (Or rather, the format of the token is mandated by the scope of the WWW-Authentication header in the 401 response.) So, if scope is WebID-OIDC, that requires tokens to be formatted a certain way (either flat JWTs or nested PoP tokens).

there’s no provision for multiple protection spaces (realms) with different security policies at the same origin.

Right. Solid does not support multiple security realms within one origin. (Or rather, the WAC ACL system lets each resource to act as a separate independent realm within an origin).

@zenomt
Copy link
Contributor Author

zenomt commented Aug 13, 2019

replies to a few points.

regarding token revocation:

there’s no reasonable way for the resource server (or its authorization infrastructure) to revoke one of these tokens.

Not quite the case. The RS can revoke a token simply by refusing to honor it, for whatever reason.

sure. the "no reasonable way" part refers to how to implement it. the server could remember that it doesn't like the webid (which could potentially affect other authenticated sessions, like from other devices), or that it doesn't like the cnf key, or some other unique claim of the token, or the entire token, or a hash of it. the server would need to remember this for the validity period of the token, which could be arbitrarily long (and not up to the server).

"reasonable" ways of revoking a token include "forgetting it from the list of valid tokens" or "remember (maybe just a hash of) it in a list of revoked tokens until it's no longer valid, which is always bounded to a reasonable period of time that the server is willing to remember stuff for".

regarding realms:

Right. Solid does not support multiple security realms within one origin. (Or rather, the WAC ACL system lets each resource to act as a separate independent realm within an origin).

as we discussed in gitter (more for everybody else here in the Issue), multiple realms per origin is a fundamental part of HTTP authorization. today's Solid client implementations may not support multiple realms per origin (which would mainly require using heuristics to discover the extent of different realms and remembering which tokens go with which realm), and the PoP tokens span them (because the aud is the origin). WAC is orthogonal to realms -- from RFC 7235:

These realms allow the protected resources on a server to be partitioned into a set of protection spaces, each with its own authentication scheme and/or authorization database.

from the gitter discussion, consider two Solid-compatible LDP servers mounted to different paths on an nginx-like reverse proxy. each one is running its own authentication/authorization system, and each would therefore be in its own independent realm (by definition, and hopefully also announced that way in the WWW-Authenticate header). if one of them decides to revoke an access token (for whatever reason and by whatever means, see above), then the client should be able to do the right thing with both realms.

@dmitrizagidulin
Copy link
Member

dmitrizagidulin commented Aug 13, 2019

multiple realms per origin is a fundamental part of HTTP authorization

Although it is mentioned in the WWW-Authenticate header spec, multiple realms (or realms in general) is not really widely used. Specifically, the realm mechanism is used for http Basic auth, and it was used for OpenID 2.0, but was deprecated and removed in OpenID Connect. Can you think of other crucial usages of it, that Solid needs to support?

consider two Solid-compatible LDP servers mounted to different paths on an nginx-like reverse proxy

So, my question about that setup is - why wouldn't those two servers just be mounted on two separate subdomains, via that same reverse proxy? There's no good reason these days to run two separate auth* systems on different paths of a single origin. For example, as LiveJournal found out, there are significant security benefits to giving each user their own subdomain (and so they moved their profile model from example.com/~user/ to user.example.com).

Also, in terms of TLS certs, it used to be expensive to get wildcard TLS certificates (which could explain the desire for serving different systems off the same subdomain). But these days, with Lets Encrypt, wildcard certs are free, which removes that concern.

Like, I'm not against the realm mechanism (we do return the realm="https://<pod server url>" param in the WWW-Authenticate header in 401 responses, we just don't use it for anything). It just seems unnecessary, with no pressing use case.

@dmitrizagidulin
Copy link
Member

As a result of the discussion so far, I opened a couple of new issues:

@zenomt
Copy link
Contributor Author

zenomt commented Aug 13, 2019

we had another call this morning (for folks who missed the schedule change) where it was suggested i link more prominently to my proposed solution to the bullet points in this issue's description.

https://github.com/zenomt/webid-auth-protocol addresses the concerns i enumerated above.

i made a reference implementation (auth server and command-line token getter) of that proposed auth protocol at https://github.com/zenomt/webid-auth-nginx .

@zenomt
Copy link
Contributor Author

zenomt commented Aug 13, 2019

Like, I'm not against the realm mechanism [...]. It just seems unnecessary, with no pressing use case.

i'd be happy saying in the spec something like "hey clients, don't forget about realms!", and maybe punting on it in a reference implementation until a situation comes up where it's needed. i think that kind of situation might arise further down the line when Solid becomes more standard™, and its principles (like LDP servers) are more ubiquitous. in enterprise systems today at least it's not uncommon at all for applications to be mounted to different paths on the same origin. and in enterprises (like the one i work at), wildcard certificates are very not-free, and Let's Encrypt is not an option.

@dmitrizagidulin
Copy link
Member

@zenomt I see, thanks.

@dmitrizagidulin
Copy link
Member

@zenomt Question about the cost aspect, though. Do you find it the case (in enterprise environment) where the cost of a single additional certificate (for a specific subdomain) outweighs the security downsides to using multiple realms per domain?

@zenomt
Copy link
Contributor Author

zenomt commented Aug 13, 2019

@dmitrizagidulin sorry, i didn't mean to imply that a wildcard certificate was exorbitant (though last time i looked at the prices we pay at Day Job i'm glad i wouldn't have to pay out of my own pocket!). i merely wanted to challenge the notion that they are "free", and to challenge that (specifically) Let's Encrypt is a viable alternative in enterprise deployments.

the Same Origin concept definitely applies even in enterprises. i don't think that multiple realms per domain constitutes a "security downside"; rather, it is (or would not unreasonably be) a deployment reality where distinct trusted applications run in the same origin.

the main point i want to make about realms is that (presumably) not every resource server a Solid client will want to access will be a Personal Online Datastore. i think prohibiting, rather than acknowledging, a valid mode of web access would be detrimental in the long term.

@dmitrizagidulin
Copy link
Member

@zenomt Got it, I think I understand what you're saying. Thanks!

@elf-pavlik
Copy link
Member

  • there’s no way for the resource server to force a current/timely proof of possession of the confirmation key.

Since DPoP requires signature for each request, including http method and request uri, it seems to address this concern.

@zenomt
Copy link
Contributor Author

zenomt commented Dec 17, 2019

Since DPoP requires signature for each request, including http method and request uri, it seems to address this concern.

not exactly. the DPoP request/signature could have been generated at any time in the past. signing an unguessable/unforgeable server-chosen value proves an unforgeable "comes-after" temporal relationship.

@dmitrizagidulin
Copy link
Member

@zenomt - so, I'm still slightly unclear on what threat model the nonce in the response is supposed to address.

@zenomt
Copy link
Contributor Author

zenomt commented Dec 17, 2019

@dmitrizagidulin it addresses two main concerns:

  1. current/now ("comes-after" the challenge) possession and control of the key
  2. the opportunity for the server to contribute to/salt the cryptographic computation (the "nothing up my sleeve" prover)

@acoburn acoburn added the can-be-closed? This issue is slated to be closed label Jan 15, 2021
@acoburn
Copy link
Member

acoburn commented Jan 25, 2021

The objections here have been noted. That said, the panel consensus has been to proceed with DPoP + bearer tokens.

@acoburn acoburn closed this as completed Jan 25, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
can-be-closed? This issue is slated to be closed
Projects
None yet
Development

No branches or pull requests

4 participants