In apps/backend/src/routes/auth.ts, both the GitHub and Google OAuth callbacks redirect to the mobile app with the JWT token as a plain query parameter:
return reply.redirect(`${mobileRedirect}?token=${token}`);
This means the JWT token (valid for 30 days) is:
- Visible in server access logs
- Stored in browser/webview history
- Potentially captured by analytics or proxy tools
- Exposed to any third-party JavaScript that reads
location.href
Expected behaviour
The JWT should be passed via a secure mechanism — for example, via a short-lived one-time code that the mobile app exchanges for the token server-side (PKCE flow), or at minimum via a URL fragment (#token=...) which is not sent to servers in HTTP logs.
Proposed fix
Use a URL fragment instead of a query parameter as an immediate improvement:
return reply.redirect(`${mobileRedirect}#token=${token}`);
Or implement a short-lived one-time code exchange endpoint for production security.
Files to touch
apps/backend/src/routes/auth.ts
GSSoC 2026 — Assignment Request
I would like to work on this issue as part of GSSoC'26. I have reviewed the codebase and understand the root cause and the fix required.
Could you please assign this issue to me?
GitHub: @MehtabSandhu11
Thank you!
In
apps/backend/src/routes/auth.ts, both the GitHub and Google OAuth callbacks redirect to the mobile app with the JWT token as a plain query parameter:This means the JWT token (valid for 30 days) is:
location.hrefExpected behaviour
The JWT should be passed via a secure mechanism — for example, via a short-lived one-time code that the mobile app exchanges for the token server-side (PKCE flow), or at minimum via a URL fragment (
#token=...) which is not sent to servers in HTTP logs.Proposed fix
Use a URL fragment instead of a query parameter as an immediate improvement:
Or implement a short-lived one-time code exchange endpoint for production security.
Files to touch
apps/backend/src/routes/auth.tsGSSoC 2026 — Assignment Request
I would like to work on this issue as part of GSSoC'26. I have reviewed the codebase and understand the root cause and the fix required.
Could you please assign this issue to me?
GitHub: @MehtabSandhu11
Thank you!