In the browser verification flow of Kratos, the CSRF check is not performed during code verification.
iBakuman opened this issue · comments
Preflight checklist
- I could not find a solution in the existing issues, docs, nor discussions.
- I agree to follow this project's Code of Conduct.
- I have read and am following this repository's Contribution Guidelines.
- I have joined the Ory Community Slack.
- I am signed up to the Ory Security Patch Newsletter.
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.