One Step Off Spec

A browser app runs the authorization code flow with PKCE. Exactly one step below violates the current OAuth 2.0 security best current practice.

1. app -> AS   GET /authorize?response_type=code&client_id=northwind-web
                 &redirect_uri=https://app.northwind.io/cb&state=8fk2
                 &code_challenge=E9Melhoa2Ow...&code_challenge_method=S256

2. AS          authenticates the user, stores the challenge next to the code

3. AS          accepts the redirect_uri because it matches the client's
                 registered pattern  https://*.northwind.io/cb
   AS -> app   302 https://app.northwind.io/cb?code=SplxlOBeZQ&state=8fk2

4. app         compares the returned state to the 8fk2 it stored pre-redirect

5. app -> AS   POST /token  grant_type=authorization_code&code=SplxlOBeZQ
                 &redirect_uri=https://app.northwind.io/cb
                 &client_id=northwind-web&code_verifier=dBjftJeZ4CVP...

6. AS          SHA-256 hashes the verifier, base64url encodes it, compares
                 it to the stored challenge, returns invalid_grant on mismatch

7. AS -> app   200 {"access_token": "...", "refresh_token": "..."}

Which step is the violation?

A

Step 5. A client that cannot authenticate must not be allowed to send client_id in the token request body, because that is an unauthenticated claim of identity.

B

Step 3. Redirect URIs must be compared by exact string match, so a registered wildcard pattern turns any subdomain the attacker can obtain into a valid landing site for the code.

C

Step 4. The state value is compared after the authorization server has already delivered the code, which is too late to prevent the redirect.

D

Step 6. Verifying the S256 transform is the client's job; an authorization server that recomputes the hash has to store the challenge and becomes a second place the secret can leak.