Skip to content

fix: delete the PKCE request session only after a successful verification#883

Open
shilps1583 wants to merge 1 commit into
ory:masterfrom
shilps1583:fix/pkce-delete-session-after-verify
Open

fix: delete the PKCE request session only after a successful verification#883
shilps1583 wants to merge 1 commit into
ory:masterfrom
shilps1583:fix/pkce-delete-session-after-verify

Conversation

@shilps1583

@shilps1583 shilps1583 commented Jul 15, 2026

Copy link
Copy Markdown

HandleTokenEndpointRequest deletes the stored PKCE request session
immediately after fetching it, before the verifier has been checked
against the bound challenge. A failed verification (wrong verifier,
disallowed method, PKCE not enforced but a challenge existed, etc.)
still leaves the session deleted.

That session is what binds an authorization code to its
code_challenge. Once it's gone, the same code can be replayed at the
token endpoint with no code_verifier at all: GetPKCERequestSession
returns ErrNotFound, nv == 0, and validateNoPKCE lets the exchange
through as a non-PKCE request (unless EnforcePKCE is on). A failed
PKCE attempt against a code should not make a second, verifier-less
attempt against that same code succeed -- that's a downgrade from a
PKCE-protected exchange to an unprotected one.

Move the delete to the two points where the session's job is actually
done: a confirmed challenge/verifier match, and the non-PKCE path
where no challenge was ever bound and none is required. A verifier
presented against a session with no bound challenge is also consumed,
since there is no challenge there for a downgrade to strip. Every other
error path (validate() failures, verifier format failures, a
challenge/verifier mismatch) now leaves the session in place.

TestHandleTokenEndpointRequest_SessionLifecycle covers both outcomes;
two of its five cases fail against the prior behavior.

Summary by CodeRabbit

  • Bug Fixes

    • Improved PKCE session lifecycle handling during token exchanges.
    • PKCE request sessions are now deleted only after appropriate verifier/challenge confirmation, and handled consistently for non-PKCE and error cases.
    • Prevented replay/downgrade scenarios where sessions could be removed or preserved incorrectly.
  • Tests

    • Added end-to-end coverage for PKCE session consumption/preservation across successful verification, mismatched verifier, missing verifier, non-PKCE, and invalid-grant scenarios.

@shilps1583
shilps1583 requested review from a team and aeneasr as code owners July 15, 2026 10:10
@CLAassistant

CLAassistant commented Jul 15, 2026

Copy link
Copy Markdown

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

PKCE session lifecycle

Layer / File(s) Summary
Session consumption flow
handler/pkce/handler.go
Token endpoint handling defers PKCE session deletion, consumes sessions for valid non-PKCE exchanges and missing-challenge verifier submissions, and centralizes deletion error handling.
Session lifecycle validation
handler/pkce/handler_test.go
Tests verify session consumption and preservation across successful, failed, incomplete, and non-enforced PKCE exchanges.

Estimated code review effort: 2 (Simple) | ~10 minutes

Suggested reviewers: aeneasr

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly and concisely describes the main PKCE session-deletion fix.
Description check ✅ Passed The description explains the bug, why it matters, the fix, and test coverage; only optional checklist items are unfilled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…rification

HandleTokenEndpointRequest deletes the stored PKCE request session
immediately after fetching it, before the verifier has been checked
against the bound challenge. A failed verification (wrong verifier,
disallowed method, PKCE not enforced but a challenge existed, etc.)
still leaves the session deleted.

That session is what binds an authorization code to its
code_challenge. Once it's gone, the same code can be replayed at the
token endpoint with no code_verifier at all: GetPKCERequestSession
returns ErrNotFound, nv == 0, and validateNoPKCE lets the exchange
through as a non-PKCE request (unless EnforcePKCE is on). A failed
PKCE attempt against a code should not make a second, verifier-less
attempt against that same code succeed -- that's a downgrade from a
PKCE-protected exchange to an unprotected one.

Move the delete to the two points where the session's job is actually
done: a confirmed challenge/verifier match, and the non-PKCE path
where no challenge was ever bound and none is required. A verifier
presented against a session with no bound challenge is also consumed,
since there is no challenge there for a downgrade to strip. Every other
error path (validate() failures, verifier format failures, a
challenge/verifier mismatch) now leaves the session in place.

TestHandleTokenEndpointRequest_SessionLifecycle covers both outcomes;
two of its five cases fail against the prior behavior.
@shilps1583
shilps1583 force-pushed the fix/pkce-delete-session-after-verify branch from 70de8eb to be6b58a Compare July 15, 2026 10:17
@shilps1583 shilps1583 changed the title fix(pkce): delete the PKCE request session only after a successful verification fix: delete the PKCE request session only after a successful verification Jul 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants