fix(oauth): reject plain PKCE method per OAuth 2.1 spec - #2669
Open
georgelzrc wants to merge 1 commit into
Open
Conversation
OAuth 2.1 (draft-ietf-oauth-v2-1-12, Section 4.1.1) explicitly removes support for the plain code_challenge_method. Only S256 is permitted. With plain, code_challenge == code_verifier, and code_challenge is transmitted in the authorization request URL, which routinely appears in server access logs, browser history, Referer headers, and CDN logs. An attacker with read access to any of those can immediately replay the authorization code using code_verifier = code_challenge, defeating PKCE's proof-of-possession guarantee entirely. Changes: - validatePKCEParams(): reject any method other than S256 - VerifyPKCEChallenge(): remove the plain case (falls through to default which returns PKCEInvalidCodeMethodError) - pkce_test.go: update plain cases to expect errors - authorize_test.go: add TestValidatePKCEParams_OAuth21 Ref: https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-4.1.1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
validatePKCEParams()inauthorize.goacceptscode_challenge_method=plain.VerifyPKCEChallenge()insecurity/pkce.goverifies it by comparingcode_challenge == code_verifierwith constant-time compare.OAuth 2.1 (draft-ietf-oauth-v2-1-12, §4.1.1) explicitly removes support for
plain:Why it matters
With
plain,code_challenge = code_verifieris sent unencrypted in theauthorization request URL (
GET /oauth/authorize?code_challenge=<value>&...).This URL routinely appears in:
An attacker who can read any of those can immediately replay the authorization
code by supplying
code_verifier = code_challengein the token exchange,defeating PKCE's proof-of-possession guarantee entirely.
With S256 this is impossible:
code_challenge = BASE64URL(SHA256(code_verifier))is a one-way transform.
Changes
internal/api/oauthserver/authorize.go—validatePKCEParams(): reject anycode_challenge_methodother thanS256with a clear error message referencingthe spec.
internal/security/pkce.go—VerifyPKCEChallenge(): remove theplaincase so it falls through to
defaultreturningPKCEInvalidCodeMethodError.internal/security/pkce_test.go: update allplaincases to expect errors.internal/api/oauthserver/authorize_test.go: addTestValidatePKCEParams_OAuth21covering S256 accepted, plain/PLAIN/rs256 rejected, and missing-param cases.
References