From 74664d3fe037a354e180e305135c6bab1747a6b0 Mon Sep 17 00:00:00 2001
From: Jonathan Huot <jonathan.huot@gmail.com>
Date: Sat, 11 Jul 2026 13:15:29 +0200
Subject: [PATCH] Improve PKCE code comparison

---
 CHANGELOG.rst                                             | 3 ++-
 oauthlib/oauth2/rfc6749/grant_types/authorization_code.py | 8 +++++---
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/oauthlib/oauth2/rfc6749/grant_types/authorization_code.py b/oauthlib/oauth2/rfc6749/grant_types/authorization_code.py
index 6c4bfce4..1806cee8 100644
--- a/oauthlib/oauth2/rfc6749/grant_types/authorization_code.py
+++ b/oauthlib/oauth2/rfc6749/grant_types/authorization_code.py
@@ -4,6 +4,7 @@
 """
 import base64
 import hashlib
+import hmac
 import json
 import logging
 
@@ -44,9 +45,10 @@ def code_challenge_method_s256(verifier, challenge):
 
     .. _`Section 4.3`: https://tools.ietf.org/html/rfc7636#section-4.3
     """
-    return base64.urlsafe_b64encode(
+    expected = base64.urlsafe_b64encode(
         hashlib.sha256(verifier.encode()).digest()
-    ).decode().rstrip('=') == challenge
+    ).decode().rstrip('=')
+    return hmac.compare_digest(expected, challenge)
 
 
 def code_challenge_method_plain(verifier, challenge):
@@ -58,7 +60,7 @@ def code_challenge_method_plain(verifier, challenge):
 
     .. _`Section 4.3`: https://tools.ietf.org/html/rfc7636#section-4.3
     """
-    return verifier == challenge
+    return hmac.compare_digest(verifier, challenge)
 
 
 class AuthorizationCodeGrant(GrantTypeBase):
