Competing refresh token requests can cause concurrent update issues on PostgreSQL
Preflight checklist
- [X] I could not find a solution in the existing issues, docs, nor discussions.
- [X] I agree to follow this project's Code of Conduct.
- [X] 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
When executing two token refresh requests in parallel, with the same OAuth2 Client ID and OAuth2 Refresh Token, a situation may arise where:
- First request succeeds, second request fails with 400
- First request fails with 500, second succeeds with 200
- First request fails with 400, second with 401
Error payloads are as follows:
"payload": {
"error": {
"debug": "Unable to serialize access due to a concurrent update in another session: The request could not be completed due to concurrent access",
"message": "invalid_request",
"reason": "Failed to refresh token because of multiple concurrent requests using the same token which is not allowed.",
"status": "Bad Request",
"status_code": 400
},
"payload": {
"error": {
"debug": "Unable to serialize access due to a concurrent update in another session",
"message": "server_error",
"reason": "",
"status": "Internal Server Error",
"status_code": 500
},
Reproducing the bug
- Create a client
- Issue access + refresh token
- Try to refresh the same token multiple times in parallel
Relevant log output
No response
Relevant configuration
No response
Version
master
On which operating system are you observing this issue?
None
In which environment are you deploying?
None
Additional Context
I believe the issue is that we have one big transaction that is used for refresh tokens. It:
- Begin
- Deletes old access token
- Deletes the old refresh token
- Writes new access token
- Writes new refresh token
- Commit
The code for this is here:
https://github.com/ory/fosite/blob/1df109bb45fadd90b34c3d15cbc7431426cc9853/handler/oauth2/flow_refresh.go#L136-L167
Kind of related: https://github.com/ory/hydra/issues/1831
There are two ways to fix this:
- Do not return a 500 error when this happens but instead a human-readable error message like "You tried to refresh the same token twice, at the same time. Please ensure your clients are refresh tokens only once".
- Solve https://github.com/ory/hydra/issues/1831 (this needs a very clear design doc as it can lead to several access+refresh token chains being valid, which may be a security issue).
I'm having similar issue. I use hydra for oauth2 flow. Third-party service that I don't control (make.com in my case) seems to send 2 parallel token refresh requests. I see it from proxy access logs. Then I see error in hydra logs same as described in an issue. End user loses his auth in make.com due to that error and complains to me about it.
Looking for any possible workaround for this issue 🙏
Same issue on our side using react-oidc-context. The issue results in random disconnections for our users, I would say it's a critical problem.