OAuth callback redirects relative redirect_url to the API origin in split-domain deployments
- Dominant language
- TypeScript
- Stars
- 156k
- Forks
- 24.6k
- Avg merge
- 22h 9m
- Merged PRs (30d)
- 610
Description
### Self Checks
- [x] I have read the [Contributing Guide](https://github.com/langgenius/dify/blob/main/CONTRIBUTING.md) and [Language Policy](https://github.com/langgenius/dify/issues/1542).
- [x] This is only for bug report, if you would like to ask a question, please head to [Discussions](https://github.com/langgenius/dify/discussions/categories/general).
- [x] I have searched for existing issues [search for existing issues](https://github.com/langgenius/dify/issues), including closed ones.
- [x] I confirm that I am using English to submit this report, otherwise it will be closed.
- [x] 【中文用户 & Non English User】请使用英语提交,否则会被关闭 :)
- [x] Please do not modify this template :) and fill in all the required fields.
### Dify version
main (cf88aef710); regression introduced in 82ff93cbdd8 (#38900)
### Cloud or Self Hosted
Self Hosted (Source)
### Steps to reproduce
1. Configure the Console web app and Console API on different origins:
- CONSOLE_WEB_URL=http://web.dev.com
- CONSOLE_API_URL=http://api.dev.com
2. Open http://web.dev.com/ with an expired Console session. The normal login flow preserves the current page as redirect_url=/.
3. Complete login with a Console OAuth provider (GitHub or Google).
4. Inspect the final redirect returned by /console/api/oauth/authorize/.
The OAuth state contains {"redirect_url":"/"}.
### ✔️ Expected Behavior
A safe relative redirect_url should be resolved against CONSOLE_WEB_URL before the OAuth callback returns its redirect response.
For redirect_url=/, the response should redirect to:
http://web.dev.com/?oauth_new_user=false
The behavior should also preserve same-origin absolute Console URLs and continue to fall back to CONSOLE_WEB_URL for cross-origin or protocol-relative URLs.
### ❌ Actual Behavior
The post-login callback calls _get_redirect_target(), which returns a safe relative redirect_url unchanged. The callback therefore returns:
Location: /?oauth_new_user=false
Because this response comes from the API origin, the browser resolves it as:
http://api.dev.com/?oauth_new_user=false
The API does not serve the Console at /, so login ends at a Flask 404 page. This affects Console OAuth login when the web and API services use different origins.
A minimal fix is to resolve validated relative paths under CONSOLE_WEB_URL instead of returning them as relative Location values.
Contributor guide
Research direction
Start at the OAuth callback and _get_redirect_target(), then trace how CONSOLE_WEB_URL and redirect_url are handled. Reproduce the split-domain flow with separate web and API origins, checking relative, same-origin absolute, cross-origin, and protocol-relative URLs. Done means the callback returns the Console origin for safe relative paths and preserves the stated fallback behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- flask, python
- Domain
- api, authentication, backend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 68/100