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

feat: redirect to OIDC providers only once in registration flows #3416

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

Saancreed
Copy link
Contributor

@Saancreed Saancreed commented Aug 3, 2023

Removes the requirement to redirect to OIDC providers more than once in registration flows where Jsonnet mapper is unable to provide all required identity traits.

Related issue(s)

#2863

Checklist

  • I have read the contributing guidelines.
  • I have referenced an issue containing the design document if my change
    introduces a new feature.
  • I am following the
    contributing code guidelines.
  • I have read the security policy.
  • I confirm that this pull request does not address a security
    vulnerability. If this pull request addresses a security vulnerability, I
    confirm that I got the approval (please contact
    [email protected]) from the maintainers to push
    the changes.
  • I have added tests that prove my fix is effective or that my feature
    works.
  • I have added or changed the documentation.

Further Comments

While the change itself is relatively small, I have no tests to verify it (yet!) and the way I chose to resolve it (by persisting received claims and ID/Access/Refresh tokens in internal context) may not be the best idea. On the other hand, this allows us to simply continue the flow as if we were already after the redirect and does not rely on clients setting proper login_hint or the provider even respecting this parameter which as far as I know is not guaranteed or could require the user to supply their credentials again.

This is pretty much my first piece of code I've written in Go and my first dive into Kratos' codebase so please be gentle. That said, I'm submitting this to provide some context for questions I'd like to have answered and with them out of they way, I hope I'll be able to get this PR in shape so one day it could be merged.

  1. What kind of test should I add? Would something similar to OIDC linking tests for settings flow be okay or should I try to prepare some e2e scenarios as well?
  2. Is using internal context to persist initial provider ID, tokens and claims acceptable? Should I persist more so it's harder to continue the flow with bogus data? Right now I'm verifying that provider ID stays the same although I'm not sure if this is actually needed.
  3. I'm storing tokens encrypted but claims unencrypted, perhaps I should encrypt claims as well?
  4. The process of storing data into internal context is done on a best effort basis and any errors are silently ignored, in which case the user will be redirected again as before. However, when reading this data any error is considered fatal and interrupts the flow if it's found to have previously been stored after first callback.

Copy link
Member

@aeneasr aeneasr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice job! Great to see your first Go code! :)

This indeed needs some test code to ensure that it does what we expect it to do. This would probably need to be done in Cypress e2e tests. We also need to consider potential security impact of this feature. Right now, we can pretty much assume that the OIDC linking is always accurate (because we always re-initiate the flow). Without this, we need other strong guarantees that the user who performs the registration flow is also indeed the user who performed the OIDC flow.

@Saancreed Saancreed force-pushed the feat/oidc-registration-single-redirect branch from 4b97280 to 13b1842 Compare August 18, 2023 13:52
@Saancreed Saancreed requested a review from hperl as a code owner August 18, 2023 13:52
@Saancreed Saancreed force-pushed the feat/oidc-registration-single-redirect branch from 13b1842 to 14ae228 Compare August 18, 2023 13:58
@Saancreed
Copy link
Contributor Author

There is now an e2e test that verifies only one redirect to OIDC provider takes place. I wasn't sure what are the exact URLs I should be looking for so I'm intercepting everything that looks like such a redirect and it seems to work.

About the security impact, I can imagine an attacker hijacking a registration flow if its ID was somehow leaked but unless there is a session post-registration hook, this is no worse than hijacking registrations using other methods. But we will consider this more thoroughly and come back with a detailed analysis soon.

@codecov
Copy link

codecov bot commented Aug 18, 2023

Codecov Report

Attention: 20 lines in your changes are missing coverage. Please review.

Comparison is base (492808c) 78.41% compared to head (45353fa) 78.37%.
Report is 1 commits behind head on master.

Files Patch % Lines
selfservice/strategy/oidc/strategy_registration.go 28.57% 19 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3416      +/-   ##
==========================================
- Coverage   78.41%   78.37%   -0.04%     
==========================================
  Files         344      344              
  Lines       23487    23515      +28     
==========================================
+ Hits        18417    18431      +14     
- Misses       3686     3701      +15     
+ Partials     1384     1383       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

@jakubfijalkowski
Copy link

So, after giving it some thought (and observing the behavior), we think it should be safe already, provided that we haven't missed something obvious (or you asked for something different and we just completely misunderstood).

It basically boils down to leaked flow id . If it does not leak the system (native app or browser app) that initiates the flow, we are safe. Also, it won't be a problem if the session hook is not enabled (because the only thing that the hijacker can do is to complete the flow early, without being able to sign in because they can't do the OIDC flow). They might see some data from OIDC claims, but I would consider that only a minor problem (but I don't think this is possible either, so bear with me).

Let's also exclude MITM attacks. Here, the attacker might just wait and hijack the session cookie/token directly.

We also need to consider only the case when the user is taken back to registration interface to fix form errors (e.g. missing traits), otherwise the flow will end the moment first redirect concludes, which was not affected by this PR and the same security guarantees hold.

Let's consider how can we prevent the leaked flow id when the user is redirected back to app with some error.

Native

Here, we can't do much - it boils down to whether the native app keeps flow id safe.

Since flow id will be kept in memory (most of the time; I can't really see a reason why it would be kept anywhere else), it is harder to hijack than session token that will be stored more permanently. If attacker can get access to flow id, they can access the token that will be retrieved soon after.

Browser

Here, the registration flow is already bound to the anti-CSRF token that is HTTPOnly. If the anti-CSRF token is not present, Kratos will start a new, empty flow. Thus, the only case where this can be a problem is if the attacker can get hold on the cookie. And if they can, then they can probably wait and get access to the session cookie.


What do you think?

@Saancreed Saancreed force-pushed the feat/oidc-registration-single-redirect branch from 14ae228 to b2e87ac Compare August 23, 2023 09:01
@Saancreed Saancreed requested a review from aeneasr August 25, 2023 09:00
@Saancreed Saancreed force-pushed the feat/oidc-registration-single-redirect branch from b2e87ac to 3dd152b Compare September 18, 2023 13:19
@Saancreed Saancreed marked this pull request as draft September 20, 2023 14:52
@Saancreed Saancreed force-pushed the feat/oidc-registration-single-redirect branch from 3dd152b to d9ae6a1 Compare November 9, 2023 13:27
@Saancreed Saancreed force-pushed the feat/oidc-registration-single-redirect branch from d9ae6a1 to 45353fa Compare November 20, 2023 12:42
@David-Wobrock
Copy link
Contributor

Hey 👋

This patch looks amazing, and we'd love for it to be merged.
How can we help? 😁

@Saancreed Saancreed force-pushed the feat/oidc-registration-single-redirect branch from 45353fa to e49da72 Compare August 21, 2024 13:46
@Saancreed
Copy link
Contributor Author

Hey @David-Wobrock, I admit this PR was slightly abandoned because I started seeing some e2e test failures for reasons that I couldn't explain and never had enough time to figure this out. I rebased my changes and pushed updated version but I imagine the two major blockers now are:

  1. Figure out what's going wrong in e2e tests, assuming there are still some issues with them.
  2. Attract some attention from Ory again to get some feedback on the writeup above.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants