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

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions