ory / kratos

The most scalable and customizable identity server on the market. Replace your Homegrown, Auth0, Okta, Firebase with better UX and DX. Has all the tablestakes: Passkeys, Social Sign In, Multi-Factor Auth, SMS, SAML, TOTP, and more. Written in Go, cloud native, headless, API-first. Available as a service on Ory Network and for self-hosters.
https://www.ory.sh/?utm_source=github&utm_medium=banner&utm_campaign=kratos
Apache License 2.0
11.21k stars 959 forks source link

Native flow ignores redirect_to in oidc flow if session in browser already established #3543

Open luflow opened 1 year ago

luflow commented 1 year ago

Preflight checklist

Ory Network Project

selfhosted

Describe the bug

We found a strange behavior in Kratos thats somehow leading to ignoring our set redirect_to URL and always falling back to the default_browser_return_url. It happens in the case where a session in a browser is already established, but afterwards an API native flow is started with a 3rd-party Login. The app opens the browser, the session at the 3rd party is still valid so redirects are taking place and then I suddenly land on default_browser_return_url instead of the redirect_to specified in the API call.

Reproducing the bug

Steps to reproduce behavior:

Precondition: You need a native app where the native login flow can be executed with the Kratos API

  1. Setup kratos with an OIDC flow e.g. with GitHub including some simple mapping (email and firstname)
  2. Setup correct allowed_return_urls and default_browser_return_url for your selfservice flows
  3. Use an android device (where sessions in browser are shared between a native app and browser)
  4. Open the android browser and login to your website with the GitHub OIDC integration, stay logged in
  5. Go to your native app and start a native login flow via the API with the GitHub OIDC integration with a redirect_to to myapp://module/login
  6. After the flows redirects in the browser are done, now you will not be redirected correctly to myapp://module/login but instead to default_browser_return_url

Somehow it looks like the redirect_to information gets lost on the way?

As soon as I logout in the browser manually and start from Step 5 again - everything works as intended and the native app flow gets completed correctly.

Relevant log output

no errors shown in logs.

Relevant configuration

selfservice:
  default_browser_return_url: https://yourwebsite.com
  allowed_return_urls:
    - https://yourwebsite.com/auth
    - https://yourwebsite.com/

    # App Links
    - myapp://
    - myapp://module/login
  methods:
    profile:
      enabled: true
    password:
      enabled: true
    link:
      enabled: true
    code:
      enabled: true
    oidc:
      config:
        providers:
          - id: github
            provider: github
            client_id: <enter client id>
            mapper_url: "base64://bG9jYWwgY2xhaW1zID0gewogIGVtYWlsX3ZlcmlmaWVkOiBmYWxzZSwKfSArIHN0ZC5leHRWYXIoJ2NsYWltcycpOwp7CiAgaWRlbnRpdHk6IHsKICAgIHRyYWl0czogewogICAgICBbaWYgJ2VtYWlsJyBpbiBjbGFpbXMgJiYgY2xhaW1zLmVtYWlsX3ZlcmlmaWVkIHRoZW4gJ2VtYWlsJyBlbHNlIG51bGxdOiBjbGFpbXMuZW1haWwsCiAgICAgIFtpZiAnbmFtZScgaW4gY2xhaW1zIHRoZW4gJ25hbWUnIGVsc2UgbnVsbF06IHsKICAgICAgICBmaXJzdDogY2xhaW1zLm5hbWUsCiAgICAgIH0sCiAgICB9LAogIH0sCn0="
            scope:
              - user:email

Version

Kratos v1.0

On which operating system are you observing this issue?

Android & iOS (if login flow AND inapp browser is used with established session. Does not happen if you have the session in the safari app, because iOS separates inapp browser and safari app sessions)

In which environment are you deploying?

Kubernetes

Additional Context

No response

francesconi commented 1 year ago

We are encountering a related issue when using the browser flow and the user is not logged in.

aeneasr commented 1 year ago

Thank you for the report, it looks like as if some existing cookie from the previous flow is messing with the return value. Any help towards why this could be is greatly appreciated!

We are encountering a related issue when using the browser flow and the user is not logged in.

If you are experiencing the same issue please feel free to add details on the flow so it is easier to find it. If you are experiencing a different issue, please create an issue that is as detailed as the one here. Otherwise it will not be possible to understand what your problem or observed bug is.

luflow commented 1 year ago

@aeneasr Trying to understand the logic here to dig deeper and maybe come up with a solution

Is the redirect_to not pulled from the kratos database for a flow but instead always from the browser cookie (if available)? In kratos the correct redirect_to URLs are persisted in the database actually.

Shouldn't kratos prefer the database data when redirecting? Pointing me to the right piece of kratos code where this magic happens, may help with debugging - currently I am totally in the dark with this because I am also new to the codebase.