Skip to content
hashkey.bond

Archivesecurity

PKCE Is Mandatory Now, Even for Confidential Clients

The authorization code flow is only safe if the code cannot be replayed by an interceptor.

Published
Reading time
1 min read

PKCE (Proof Key for Code Exchange) binds the authorization code to the client that requested it. The client sends a hash of a random verifier with the authorization request, then presents the verifier when exchanging the code.

The attack it stops

A malicious app registers a custom URI scheme and intercepts the redirect containing code. Without PKCE, it exchanges the code for tokens. With PKCE, it lacks the verifier and the exchange fails.

Flow

verifier = random(32 bytes)
challenge = base64url(sha256(verifier))
→ /authorize?...&code_challenge=...&code_challenge_method=S256
→ redirect ?code=...
→ /token with code + code_verifier

Details

  • Always use S256, never plain.
  • Support is required by OAuth 2.1 for all clients, confidential or not.
  • PKCE does not replace state for CSRF protection, and does not authenticate the client for confidential apps.

Takeaway: PKCE is cheap and closes a real interception class. There is no good reason to ship a code flow without it.