-
Notifications
You must be signed in to change notification settings - Fork 24
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
MVP Recommendation: TOTP #36
Comments
I think this boils down to proposing that DBSC supports establishing a symmetric key (the TOTP seed), and issues a challenge-less signature based on the client time (or some epoch counter) to each request. The threat model (post-login malware) mandates that the symmetric key can be protected better than stored cookies - otherwise there is no gain. That might work but means that we're still talking about TPMs or system-level protections, so there are still some significant performance considerations even for symmetric keys. A challenge-less approach is vulnerable to transient malware: Temporary access to the signing oracle would allow malware to generate and exfiltrate future TOTP hashes at will. Granted, this is also the case in the currently proposed DBSC if servers choose to not bother with challenges. We could explore a mode of this where Sec-Secure-Session-Challenge response header values are embedded in the signature here (it wouldn't be TOTP anymore, but that's ok), freeing the browser from having to do any round-trips for refreshes. That's an option worth exploring as an additional type of instruction from the registration/refresh endpoint, and might be a good option for servers that can afford new logic on existing endpoints.
Nothing in the current DBSC proposal suggests changing any semantics of either the Set-Cookie or Cookie headers. The only cookie-related functionality it proposes is that a browser can be instructed to look for the presence of a cookie, and consult the refresh endpoint when a new one is needed. All other cookie handling, including how the refresh endpoint issues those cookies, is done via the standard headers without any modification. |
I wrote a lot of other things here, but I think it would be more helpful to jump to an actual concrete proposal: And it's important for first agree on what the long term is, we can't make sure we are picking the best short term, until there is alignment on the long term. Otherwise we'll end up building things in the short term that aren't needed but due to the fact of the "web" we'll never be able to remove them. So I guess here is my proposal: The whole refresh session call can all be abstracted into the browser, the server side doesn't need to care about any of this, no refresh session endpoint, etc... There are only two pieces of data the server needs to care about:
I'm not following why the service would need to have a For reference, this whole middle part of this diagram seems hugely complex with a lot of extra unnecessary communication between the client and the service. I'm hoping we can eliminate all of this: There are for sure current limitations of current technology to support my proposal, but if there is agreement on this optimal future state of the reality, then we learn a few things:
Again, I think it's important for agreement on the future most optimistic case, because right now the current repo proposal for DBSC dances around "well, ummm, TPM aren't that performant". Well okay, no problem, there are ways around those sorts of technical issues, for instance, why not do X or Y, but remember "here is the long term that we want". Right now it feels very much like the ultimate goal is undefined and we are just trying to throw "something" out there. Which I do totally get, but that something includes introducing the complexity of "another endpoint on the service side" which doesn't make any sense to me. Since the future I see doesn't include a need for that endpoint, it seems wrong to require the introduction at any stage. I'd must prefer to have that conversation first about the long term solution landscape here, and then figure out what the iterative path to get there. What seems to be happening right now is "let's introduce this thing that we think will be a stepping stone", because realistically I'm struggling to see how session bound credentials is better than the current state. As evidence for that refresh_token rotation in OAuth2.0 is a viable option and most if not all non-identity providers don't use that. And if you are using that, then automatically rotating session credentials seem to make this stepping stone almost completely unnecessary, right? And if someone isn't using rotating session credentials already, then it's hard to argue that they would move to this which basically does the exact same thing. |
I agree with @wparad, after taking a look at this, it seems it's overly-complex and not clear, for something that should only serve a simple purpose: "proving the user requests are coming from his browser where he initially logged in". I think maybe instead of the current approach (which I'm not sure I understood very well) this could be done with just some extra security headers. Here's my proposal:
Example headers returned only once on the initial session start at the specified URL:
This key is then saved by the server and tied to the current user session internally on the server.
Example header returned on every request after session stars:
The server then verifies this token, and checks that is not expired. Using headers instead of communicating with additional HTTP requests seems more simpler to me, and more fit for a browser protocol, historically new protocols have been introduced using headers. Doesn't seem necessary to do all the other complex extra work, such as the refreshing mechanism. Keep it simple, easy to adapt by websites. And, in the end, it's all up to the servers to decide if they will implement and respect this security protocol or not. P.S. Thanks to the team for your work on this and the idea 👍 |
First, let me reiterate to be clear: Generating the short-term tokens without server round trips is a good idea, I regret if you felt that was dismissed or misunderstood in my previous reply. The complexity of the server-round trip and using a plain old cookie is there for a reason. It has nothing to do with signing performance, but for retrofitting binding to existing infrastructure, whether it's legacy systems that are hard to change, or new web apps built on stacks where you can't (or don't want to) select a full stack that supports a new kind of authentication. It's not only about a new header vs. a cookie either, as you need to efficiently do the signature validation of such a new header, although that's more solvable (either you just do it for every request and eat the cost, or you build some scalable caches). We've tried mapping the work and coordination to do this in our setting, and it was not feasible or realistic due to the number of coordinated migrations that would have to happen. I don't think a thing like DBSC can take off unless it is realistically deployable within such existing real-world constraints. For settings where you can do anything you want we should definitely discuss if that should be additionally supported. |
There are two really important things here that I think have been left out of the evaluation that I think is imperative we add back in:
So I think I want to push back on:
Because realistically it seems like there are both simpler and more complex solutions that make this easier for both the client side and the service side. But without understanding exactly the "implementation example" you are relying on, which is trying to be solved with this the current solution, right now we are looking at something that doesn't add any security for a lot of implementations or the ease of roll-out. I.e. We know what the "solution" looks like from what is in the Explainer, and we know that this "solution" is only a very small part of the real solution (as you have graciously clarified), but we have no idea why the "real solution" isn't being rolled out and where that complexity lies (as per your latest comment). So, unfortunately to me, if feels like what is being said is We have a use case we want to solve with this and are unwilling share what that use case looks like or consider alternative proposals here. Now, I'm sure that isn't the case, but it's hard to know what the best path to continue here is. Perhaps a recommendation is getting that "example app user story" published in the Explainer, so that others can better collaborate, however I fear the criteria will be "but we can't change any app code or any server code to make this happen", which just feels like, why is this even a public proposal. Speaking from the perspective of my company with an IdP as a Service, we absolutely excited that a browser is finally onboard here and desperately want to implement something to better improve the security of our sessions for our customers/users, but it has to provide Device Bound Credentials (not Session Credentials) and it needs to be someone complaint with OAuth2 in really any way, at the very least an addition and not an official RFC, but speaking in terms of OAuth2 concepts and flows seems like table stakes. And I really appreciate your patience in all of these back and forths. |
I appreciate your patience as well!
I agree with this, but I would like to learn more how session auth on the web is based on OAuth 2 (if it goes beyond just issuing an access token in a cookie), and why DBSC driven refresh isn't in your view bringing us closer to OAuth 2 rather than further away from it. I ask because our initial motivation for this design is actually in OAuth 2 settings is that we were successful in creating binding for our native app credentials, which are OAuth 2 (the only caveat is that in our setting there is full trust between the AS and RSes, so a lot of problems that OAuth 2 solves for aren't of concern for us). For native apps on Android we bound the refresh tokens to device keys but left access tokens unbound, which enabled scale, and we already had centralized management of the RT->AT exchanges, which enabled the migration without migrating every Google Android app. (Also note when we say "session auth", we mean specifically not the user authentication flow. There are separate thoughts on how to integrate DBSC session establishment with user auth methods, such as OIDC, WebAuthn, etc. for added assurances.) |
OAuth2 works with the following required user-device <=> server communication:
To be in alignment with OAuth to work, we must utilize only these two endpoints This means that "out of bound refresh that happens" must be using the existing endpoints. Specifically:
But this also incredibly simplifies what the browser has to do, because it only needs to support two new methods:
At no point does the browser need to make any additional HTTP Requests on behalf of the site, be told how the site functions or given anything to be saved. Everything else will be magically handled by the
|
Ive been reading issues and comments for a few days, and I must say I'm having a hard time following your thoughts @wparad. To me, DBSC is orthogonal to OAuth2 or OIDC. As I understand it, DBSC is only about "session cookies". In an OAuth2/OIDC context, "session cookies" can be used at the AS/IdP/OP or RS/RP sides, and each side can use DBSC (or not) to secure them. Also, access tokens, and refreshing them, is (almost) orthogonal to "sessions"; access tokens are about calling third-party web APIs, so if a site doesn't call third-party APIs (besides OIDC UserInfo endpoint), they don't need to deal with access tokens (and signing out from the IdP/OP can be communicated to the site/RP through the various OIDC Logout extensions). Things are similar with SAML2 or Apereo CAS, or even FedCM (although FedCM is client-side, so entirely between the User-Agent and the IdP, but generally followed by establishing a session on the RP) There are many different architectures, but looking at https://datatracker.ietf.org/doc/html/draft-ietf-oauth-browser-based-apps so we can share the same terminology, we can see that cookie-based session management is used in both the BFF and Token Mediating architectures, and those sessions can thus be protected with DBSC. As a last note: I wouldn't want that a JS API be required; the current HTTP-header-based DBSC proposal looks great. |
This is exactly the problem, browsers but really any user device, can't use DPoP without support from that browser. All that needs to happen here is that instead of the duplicating DPoP at the browser level, just expose the JS interface to allow the site to perform the equivalent to the DBSC binding using the already existing DPoP semantics. The first step for DBSC is really "create the JS interface so that anyone can call the TPM", AND then the second step could be "Browser supports a full alternative to DPoP". The problem here is that the current proposal for DBSC in the explainer prevents the usage of DPoP in the browser. It is exactly the "user-agent <=> IdP" refresh_token flow that I want to secure with DBSC. You are saying it is orthogonal, it's only orthogonal because the current suggested implementation of DBSC in the explainer ignores the fact that OAuth already exists and could be simply utilized to achieve the same security DBSC wants to create without needing to also create a strategy for the browser to call the backend service via a back channel. All that we need to see happen here is "Browser support TPM integration standard that doesn't require user-verification as the current fido2 implementation basically requires." Or maybe a better way to say this is, Please support TPM integration for WebAuthN in a completely silent mediation mode that doesn't require user verification. And if we do that both DBSC and DPoP in the browsers (and really all devices) will be automatically enabled into the security that DBSC wants to provide. |
I made a comment about how to significantly reduce the complexity of the flow here: #23 (comment)
But the general response of #23 is "this is just the first step."
However the long term doesn't really align with this proposal as it is. A much better first step would be:
Over time more strategies instead of TOTP could be implemented including ones that support TPMs and signatures, but this would allow validation on the service side and use the framework on the client side without significant changes anywhere along the line.
I would strongly advise against changing the mechanism for setting cookies.
The text was updated successfully, but these errors were encountered: