Closed akkie closed 2 years ago
Thank you for the report! We do have e2e tests for this flow so it is strange that it fails for you. How did you implement your registratino screen?
Thanks for your answer. I do not use the UI parts that Kratos provides. I use the SDK and provide my own endpoints to abstract the Kratos API. The flow is as follow:
I have two registration screens:
On the Index screen I start a new registration flow. If a user clicks on the button I call submitSelfServiceRegistrationFlow. I check for status code 422 and return the redirect URL to my UI which then redirects to the OIDC provider. Then after the OIDC flow is finished, Kratos will redirect to the Email screen which then fails, because I try to get the flow for the given flow ID.
The cookies are all correctly send in both directions from the API to the UI and vice versa. It also works if I remove the username claim as example. Then the user is correctly logged in over the OIDC provider.
Do you see anything I am doing wrong that could be causing the current issue?
Hm, it's possible that there is a race condition in the network requests which causes the problem. Please check your network tab to ensure that there are no concurrent requests ending at Ory Kratos :) Also make sure to use the credentials: include
option in the SDK (see https://www.ory.sh/docs/guides/local-development)
OK, I will check that in detail. To understand it correctly, when will the CSRF token exactly be set in this flow? Is it set only once or is it set multiple times with different values?
The CSRF cookie is set if the request does not have a CSRF cookie. What can happen is that you have two requests, both without cookie, that execute at the same time. Then, you end up with two CSRF cookie values but only one value is actually valid.
I found the issue. My API has URL encoded the CSRF cookie. As a consequence, the callback endpoint couldn't read it and created a new one.
Preflight checklist
Describe the bug
If an OIDC provider doesn't provide all traits, then the CSRF token is invalid after the redirect to the registration UI.
I currently use the Google OIDC provider which is configured to return only the email address. My identity is configured to use the email and also a username. Based on the documentation, the callback endpoint of Kratos should redirect to the registration endpoint where the user can enter the missing information. The problem is that after the redirect, the error message "Please retry the flow and optionally clear your cookies. The request was rejected to protect you from Cross-Site-Request-Forgery (CSRF) which could cause account takeover, leaking personal information, and other serious security issues." will be shown if I try to load the flow for the passed flow ID.
Detailed description
Google OIDC endpoint
The google OIDC endpoint redirects the user to the Kratos callback endpoint:
https://project.app/kratos/self-service/methods/oidc/callback/google?state=...&code=...&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&authuser=0&prompt=none
Kratos callback endpoint
The Kratos callback endpoint redirect to the registration UI.
Request
Request URL: https://project.app/kratos/self-service/methods/oidc/callback/google?state=...&code=...&scope=email+profile+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile&authuser=0&prompt=none
Cookies: cookie: csrf_token_3646c96d01ef8d75739130370498e7e1cfac60d1a5e56eff1ac3333af6c84d59=BcjYv6RjV%2FbQF%2F%2BGRSlPTiHFJgkQbas%2BWfvg4Pivrrg%3D; ory_kratos_continuity=MTY1Njg3OTE4NHxEdi1CQkFFQ180SUFBUkFCRUFBQVhfLUNBQUVHYzNSeWFXNW5EQ01BSVc5eWVWOXJjbUYwYjNOZmIybGtZMTloZFhSb1gyTnZaR1ZmYzJWemMybHZiZ1p6ZEhKcGJtY01KZ0FrTW1aa05EWTFOemt0WkdabU1TMDBabVl3TFRrM1l6UXRaalZoTVRBeFpXTTFaVGhqfGht_cKbbs7gD4joS3ShPqvd6tH0Cl69UorEz1ib5yIa
Response
location: https://project.app/auth/signup/email?flow=bfe844a0-d1ed-4fc4-b302-e1a0e1824474
set-cookie: csrf_token_3646c96d01ef8d75739130370498e7e1cfac60d1a5e56eff1ac3333af6c84d59=PPtnH6F51kqubGQknPXML3mVHZg1k+nV/nkJk7njYHo=; Path=/; Domain=project.app; Max-Age=31536000; HttpOnly; Secure; SameSite=Lax set-cookie: ory_kratos_continuity=MTY1Njg3OTE4NXxEdi1CQkFFQ180SUFBUkFCRUFBQUJQLUNBQUE9fIboBpPkmxNpDQvBUiyh8QNB50nEjMco7HbyjDSbRDA-; Path=/; Expires=Tue, 02 Aug 2022 20:13:05 GMT; Max-Age=2592000; HttpOnly; Secure; SameSite=Lax
Registration UI endpoint
After the redirect it's not possible to load the flow for the given flow ID, because it's ends up with the CSRF error message. If I change the actual CSRF cookie which was send in the response from the callback endpoint to the cookie that was send to the callback endpoint, then all works as expected and I can load the flow. It looks like that the callback endpoint will override my correct CSRF cookie with a new one this isn't valid for the flow.
Request
cookie: csrf_token_3646c96d01ef8d75739130370498e7e1cfac60d1a5e56eff1ac3333af6c84d59=PPtnH6F51kqubGQknPXML3mVHZg1k+nV/nkJk7njYHo=; ory_kratos_continuity=MTY1Njg3OTE4NXxEdi1CQkFFQ180SUFBUkFCRUFBQUJQLUNBQUE9fIboBpPkmxNpDQvBUiyh8QNB50nEjMco7HbyjDSbRDA-
Please let me know if you need additional information
Reproducing the bug
Please see description above
Relevant log output
No response
Relevant configuration
No response
Version
0.10.1
On which operating system are you observing this issue?
macOS
In which environment are you deploying?
Docker Compose
Additional Context
No response