Skip to content

OAuth /rest/v1/callback continues after Flask session state mismatch (missing return) #1021

Closed

Description

@shiwani42

Issue

What is the issue?

In callback(), oauthlib MismatchingStateError returns a redirect. The Flask session check does not:

if not session.get("state") or session.get("state") != request.args["state"]:
    redirect(url_for("web.login"))  # State does not match!
credentials = flow_instance.flow.credentials
# verify_oauth2_token + session["google_id"] still run

This is the cookie binding for “this browser started this login.” fetch_token still requires a valid Google code matching the Flow singleton. A forged state alone does not skip Google.

Expected Behaviour

Mismatched or missing Flask session["state"] redirects to login and does not set google_id / name / email.

Actual Behaviour

After a successful fetch_token, a mismatched Flask state still verifies the ID token and writes the session.

Steps to reproduce

Test client: mock CREFlow.fetch_token success and id_token.verify_oauth2_token. Set session["state"] = "victim-state", request /rest/v1/callback?state=attacker-state. Session still contains google_id and email.

Success criteria

  • return redirect(...) on Flask state mismatch.
  • Test: mismatch → no google_id / email in session; verify_oauth2_token not used to establish login.
  • make lint / make mypy / make test green.

Activity

  1. Ehtasham-Yasin commented on Aug 25, 2026

    @Ehtasham-Yasin

    Hi, I’d like to work on this issue. I’ll wait for maintainer acknowledgement before starting.

  2. shiwani42 commented on Aug 30, 2026

    @shiwani42
    ContributorAuthor

    Hi @Ehtasham-Yasin, thank you for your interest!

    I’ve worked on this issue locally and am waiting for the maintainers’ review before creating the PR.

    @northdpole @Pa04rth

  3. northdpole commented on Sep 4, 2026

    @northdpole
    Collaborator

    Maintainer triage (substance): confirmed real bug.

    In callback():

    if not session.get("state") or session.get("state") != request.args["state"]:
        redirect(url_for("web.login"))  # missing return

    Without return, execution continues into token verification / session writes after a state mismatch.

    Acknowledged — open for a PR. Fix is return redirect(...). Please also add a small unit/integration test if there is an existing OAuth test harness; otherwise a focused regression test is enough.

  4. northdpole commented on Sep 4, 2026

    @northdpole
    Collaborator

    Fixed in #1047 (return redirect(...) on OAuth state mismatch in the canonical /rest/v1/auth/callback, which also covers the deprecated /rest/v1/callback alias). Merged 2026-09-04.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions