Skip to content
This repository was archived by the owner on Apr 13, 2022. It is now read-only.
This repository was archived by the owner on Apr 13, 2022. It is now read-only.

Require cross-origin requests to use bearer tokens instead of cookies? #144

Open

Description

@michielbdejong

This came up in a conversation with @kjetilk just now; he pointed me to https://github.com/solid/node-solid-server/blob/release/v5.0.0/test/integration/authentication-oidc-test.js#L269-L285 and its explanation nodeSolidServer/node-solid-server#1118 (comment) - basically I think that 200 should be a 401, and even trusted web apps (whether through server-global config or through acl:trustedApp) should only be allowed to use bearer tokens, not cookies?

cc @RubenVerborgh

Activity

  1. gobengo commented on Mar 12, 2019

    @gobengo

    2 cents:

    When building systems in the past, I generally have found clearer behavior and less security oopsies from the principle that resource servers / APIs (like solid-server) should only ever infer end-user authorization from the Authorization header, never cookies. Most of the times the resource server never needs any notion of 'session' and can be stateless. And stateless systems tend to be easier to reason about, and definitely easier to scale.

    Any relying-party web app/UI that helps a user perform a session of operations on those resources should maintain it's own session (including info to generate Authorization header values for the resource server requests) however is appropriate for that session/experience. Any technical decisions and tradeoffs about storing the session can be made completely orthogonally from technical decisions about the resource server, and e.g. data stores for sessions vs the actual resources can be scaled separately, as they usually have very different properties (transient, tiny vs durable, big).

    (This is me rationalizing why I agree with you)

  2. RubenVerborgh commented on Mar 13, 2019

    @RubenVerborgh
    Contributor

    I generally have found clearer behavior and less security oopsies from the principle that resource servers / APIs (like solid-server) should only ever infer end-user authorization from the Authorization header, never cookies.

    Having dealt with first-hand the issues that come from cookies in NSS, I agree, but just want to mention:

    a) performance (our Authorization check includes a network request, although I guess we could cache that)
    b) one step in the OIDC processs (to obtain the Authorization header) relies on a separate mechanism, such as a cookie

  3. kjetilk commented on Mar 13, 2019

    @kjetilk
    Member

    Right, so this sounds to me like a practical matter where what we can achieve on the implementation side needs to guide the spec, but it also sounds like we agree that a cookie-less authentication mechanism is desired. Fair summary?

  4. elf-pavlik commented on Mar 13, 2019

    @elf-pavlik
    Member

    From what I recall app only sets 🍪 with OP and uses PoP tokens with all the RS (which also act as RP from what I recall). Currently many deployments combine OP with personal storage which seems to result in 🍪 getting used. I use dedicated NSS instance just for OP, custom setup for WebID profile, and another instance of NSS for storage with RDF sources and another for media Non-RDF sources. Organization storages will also stay on dedicated instances. This way I'll have chance to test more general setup than all mighty pod responsible for everything.

  5. gobengo commented on Mar 13, 2019

    @gobengo

    a) performance (our Authorization check includes a network request, although I guess we could cache that)

    Yes, it's standard to cache that if you actually need to speed up performance. But that network roundtrip is actually a feature. The cache time is directly proportional (equal?) to the amount of time it takes the authorization server to 'revoke' any given key that is stolen/compromised, etc. Alternatively, for revocation, you can 'push' all revocations to each instance of the authorization server process so that it can check in memory. But at scale you may have lots of revocations and storing every revoked key or client id requires unbounded storage. To bound the storage requirements of the set of revoked keys, people use probabilistic data structures like a bloom filter, which should never have false negatives to "is this key revoked?". It may have a false positive every once in awhile, but even then you'd double check with a network roundtrip only in that rare case so it all works out.

    But I think not optimizing this at all is going to be fine for 99% of individual use cases.

    b) one step in the OIDC processs (to obtain the Authorization header) relies on a separate mechanism, such as a cookie

    If I understand what you mean, this is a cookie at the authorization server's web UI that presents the user a session to help create the Authorization across several pages (e.g. so they can have separate screens for authentication, then authorizing the client to have a JWT with certain claims, then clicking 'are you sure?'). This is still usually logically (and in many projects physically) separate from the resource server, where stateless/sessionless/cookieless is best, and also separate from the relying party, which could be all kinds of clients, some of which might be web apps that maintain their own session/cookie.

    IIRC node-solid-server might implement the logical authorization server and resource server in the same process (which is a cool convenience for the 99% who don't have their own OIDC OP running), but the cookie/session from the former might be best thought of as being orthogonal from the latter, and eventually you might want to pull the former out alltogether and have oidc-op not just be a library but able to be used as a separate networked process.

  6. RubenVerborgh commented on Mar 13, 2019

    @RubenVerborgh
    Contributor

    Yes, what @elf-pavlik and @gobengo say are correct. So we probably want to adjust the issue title to reflect this.

    @megoth The fix did mix up OP and RS auth indeed, but we did so willingly, as this was the old situation (so the benefit is that old apps like Warp start working again).

  7. elf-pavlik commented on Mar 13, 2019

    @elf-pavlik
    Member

    This is still usually logically (and in many projects physically) separate from the resource server, where stateless/sessionless/cookieless is best, and also separate from the relying party, which could be all kinds of clients, some of which might be web apps that maintain their own session/cookie.

    From: https://github.com/solid/webid-oidc-spec#relying-party-rp

    A Relying Party is a POD or a client app that has to rely on an ID Token
    that's issued by a Provider. In the spec, when Alice tries to access a resource
    on bob.com, Bob's POD acts as the Relying Party, in that interaction.
    And correspondingly, Alice's POD, alice.com, will serve as the Identity
    Provider, again for that interaction.

    Incidentally, when Alice tries to access a resource on her own POD,
    alice.com plays all of the roles -- it's both the Provider and a Relying
    Party (as well as the Resource Server).

    While Solid server doesn't have to act as OP, it looks that with WebID-OIDC solid servers practically always acts as both RP + RS. Solid apps seem to usually act as Presenter https://github.com/solid/webid-oidc-spec/blob/master/README.md#presenter

    Very likely digressing here. While currently having 🍪 session with OP makes sense. With navigator.credentials.get({... mediation: silent}) one wouldn't need any cookies solid/solid#142 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions