Skip to content

[security] OAuth state parameter is never validated in GitHub/Google callbacks — CSRF protection is non-functional #147

@MehtabSandhu11

Description

@MehtabSandhu11

In apps/backend/src/routes/auth.ts, the state query parameter is generated during the OAuth redirect but never verified in the callback handlers. The callback simply ignores state:

app.get('/github/callback', async (request, reply) => {
  const { code } = request.query; // state is never read or checked
  ...
});

This makes the CSRF protection completely non-functional. An attacker can initiate a forged OAuth flow and the server will accept it regardless of state.

Expected behaviour

The callback should verify that the state returned by GitHub/Google matches the one sent in the original redirect. Typically this is stored server-side (Redis) or in a signed cookie before the redirect.

Proposed fix

Store the generated state in a short-lived signed cookie before redirecting, then verify it matches in the callback before processing the token exchange.

Files to touch

  • apps/backend/src/routes/auth.ts
    ASSIGNMENT REQUEST — add this at the very bottom of the issue body:

I would like to work on this issue as part of GirlScript Summer of Code 2026 (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!

Metadata

Metadata

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions