Visual RFC.
ALL RFCs / RFC 9700
Read the RFC ↗
RFC 9700 / ATTACKS & DEFENSES

PKCE downgrade

16

A server that silently accepts an unbound code can undo a client’s reliance on PKCE for CSRF protection.

Related RFCs and changes

“Updates” changes part of an earlier RFC. “Obsoletes” replaces it. This list shows selected related documents.

DIAGRAM§ 4.8 ↗
RFC 9700 · § 4.8DEFENSE
3 / 3
PKCE downgradeA server that silently accepts an unbound code can undo a client’s reliance on PKCE for CSRF protection. Current state: Reject this inconsistent exchange..PKCE downgradeClientverifier BAuthorization servercode · no commitmentchallenge absentcodecode + unexpected verifierno PKCE binding → reject
03
Reject this inconsistent exchange.

A verifier must not be accepted for a code that had no challenge.

Protocol participantThreat or exceptionProtocol controlSimplified drawings · precise section references
WHAT CHANGED
RFC 6749 § 4.1RFC 9700 § 4.8.2

PKCE downgrade protection is explicit: a verifier must be rejected if the original authorization request contained no challenge.

Read the updated RFC section ↗
KEY POINT

A verifier requires a recorded challenge.

  • Servers MUST bind the presence of the challenge to the issued code.
  • If a challenge was supplied, enforce a correct verifier.
  • If no challenge was supplied, a token request containing a verifier MUST be rejected. Mandating PKCE also enforces this protection.
DETAILS

The attacker removes a challenge in their own flow and injects the resulting unbound code into a victim’s flow. This does not require breaking TLS or editing the victim’s network traffic.

Read the RFC section ↗

Diagrams simplify the RFC. Read the linked sections for complete requirements.

Privacy
All chapters in this RFC
  1. OAuth overview
  2. Authorization code + PKCE
  3. Retire unsafe grants
  4. Prevent token replay
  5. Limit token privileges
  6. Authenticate the client
  7. Metadata, TLS & CORS
  8. The attacker model
  9. Redirect URI validation
  10. Referer header leakage
  11. Browser history leakage
  12. Authorization server mix-up
  13. Authorization code injection
  14. Access token injection
  15. Cross-site request forgery
  16. PKCE downgrade
  17. Leakage at resource servers
  18. Misuse of stolen tokens
  19. Open redirection
  20. 307 credential forwarding
  21. TLS termination & proxies
  22. Refresh token protection
  23. Client as resource owner
  24. Clickjacking
  25. In-browser messaging

Drawing view

Scroll the drawing to see every part. Playback controls stay above it.

RFC 9700 / CHAPTERS

Chapters

For full details, tables, algorithms, and exceptions, read the original RFC.

RFC status and corrections ↗