ory / kratos

Next-gen identity server replacing your Auth0, Okta, Firebase with hardened security and PassKeys, SMS, OIDC, Social Sign In, MFA, FIDO, TOTP and OTP, WebAuthn, passwordless and much more. Golang, headless, API-first. Available as a worry-free SaaS with the fairest pricing on the market!

Home Page:https://www.ory.sh/kratos/?utm_source=github&utm_medium=banner&utm_campaign=kratos

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

In the browser verification flow of Kratos, the CSRF check is not performed during code verification.

iBakuman opened this issue · comments

Preflight checklist

Ory Network Project

No response

Describe the bug

During email verification, there is no check for the presence of a CSRF token. It is possible to complete the verification process without providing a CSRF token, as long as the verification code is correct.
After conducting an analysis of the source code https://github.com/ory/kratos/blob/49e1a390d555f96726fc65f8ffec4c3f607b6866/selfservice/strategy/code/strategy_verification.go#L190C1-L205C3 I have discovered that CSRF prevention occurs after the validation process (line 197 before line 203). Is there a specific reason for this implementation?

Reproducing the bug

For example, in the code snippet below, the request body(data-raw) does not include the "csrf_token" field. The request carries a flow with a "flow_type" of "browser", yet the status code of the response is 200 OK.

$ curl --location --request POST 'http://localhost:4433/self-service/login?flow=0e108b08-db10-4752-8b95-1f40fd26d4eb' \
--header 'X-Session-Token;' \
--header 'Cookie: csrf_token_d776fc2ae1b2443a7794b2134bdb17086f1b18f8f222434d43c0207f8cfeb3ae=rjTDvgeY1utNcGxQo1a+YmQf50ksbj8bJ7JzAkebHMs=' \
--header 'User-Agent: Apifox/1.0.0 (https://apifox.com)' \
--header 'Content-Type: application/json' \
--header 'Accept: */*' \
--header 'Cache-Control: no-cache' \
--header 'Host: localhost:4433' \
--header 'Connection: keep-alive' \
--data-raw '{
    "method": "password",
    "password": "pass.theplant.jp",
    "identifier": "y.kkklya@pwdyt.in"
}'

{
    "id": "ff7d14c8-f1bb-4fd8-8475-86df3e1261e4",
    "type": "browser",
    "expires_at": "2024-03-12T11:18:02.613476Z",
    "issued_at": "2024-03-12T10:18:02.613476Z",
    "request_url": "http://localhost:4433/self-service/verification/browser",
    "active": "code",
    ......
    "state": "passed_challenge"
}

Relevant log output

No response

Relevant configuration

selfservice:
  flows:
    verification:
      enabled: true
      use: code
    login:
      after:
        hooks:
          - hook: require_verified_address

Version

v1.1.0

On which operating system are you observing this issue?

macOS

In which environment are you deploying?

Docker

Additional Context

No response

Thanks for the report. This is indeed intended, as the email contains a link to the verification form. CSRF protection cannot be enforced, if the user clicks on the link, but that link opens in a different browser, than the one that started the flow (e.g. it doesn't contain the CSRF cookie).

While this does seem like a security risk, the only real value an attacker could gain from this is verifying the address. We deemed this as being an acceptable trade-off, to allow for smoother user-experience.

Thank you for your detailed answer.