Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can Authorization Code Flow with PKCE be more secure than Authorization Code Flow without client_secret

Most likely I misunderstood something about this topic or am missing something during the implementation

I went through the documentation of Auth0 for creating an Authorization Code Flow with PKCE via the endpoints and not the SDKs, I see that we make challenges and vertifiers like below (From auth0 doc):

// Dependency: Node.js crypto module
// https://nodejs.org/api/crypto.html#crypto_crypto
function base64URLEncode(str) {
    return str.toString('base64')
        .replace(/\+/g, '-')
        .replace(/\//g, '_')
        .replace(/=/g, '');
}
var verifier = base64URLEncode(crypto.randomBytes(32));

and

// Dependency: Node.js crypto module
// https://nodejs.org/api/crypto.html#crypto_crypto
function sha256(buffer) {
    return crypto.createHash('sha256').update(buffer).digest();
}
var challenge = base64URLEncode(sha256(verifier));

and then we pass the challenge to the authorize endpoint like below (From auth0 doc):

https://YOUR_DOMAIN/authorize?
    response_type=code&
    code_challenge=CODE_CHALLENGE&
    code_challenge_method=S256&
    client_id=YOUR_CLIENT_ID&
    redirect_uri=YOUR_CALLBACK_URL&
    scope=SCOPE&
    audience=API_AUDIENCE&
    state=STATE

and pass the code and vertifier to token endpoint like below (Again from auth0 doc):

curl --request POST \
  --url 'https://YOUR_DOMAIN/oauth/token' \
  --header 'content-type: application/x-www-form-urlencoded' \
  --data grant_type=authorization_code \
  --data 'client_id=YOUR_CLIENT_ID' \
  --data code_verifier=YOUR_GENERATED_CODE_VERIFIER \
  --data code=YOUR_AUTHORIZATION_CODE \
  --data 'redirect_uri=https://YOUR_APP/callback'

The implementation is a fairly straightforward thing but I can not get how another application can not make the same challenge and verifier and simulate our application?

I thought we do not use client_secret as Authorization Code Flow with exposed client_secret makes it easier for hackers to attempt token generation and false simulating our app, why can't they simply simulate the challenge and verifier?

like image 277
Mehdi Amenein Avatar asked May 18 '26 14:05

Mehdi Amenein


1 Answers

If you use authorization code flow without PKCE in an app or a SPA and somebody catches the Authorization Code that you receive from the authorization server, he would be able to retrieve an access token from the authorization token by sending the authorization code + the client ID (Key) and client secret to the authorization server. Because the ID and secret are the same for all users/clients of your app. With the access token he then could retrieve the user data from the resource server.

If you use authorization code flow with PKCE, the attacker couldn't use the Authorization Code because he doesn't have the verifier. If he creates his own verifier and code challenge and build his own version of your app, he would also need to make the user use his version of the app. Only then would the challenge and the verifier match after the user logged in at the authorization server. If he only catches the Authorization code somehow, generating an own challenge and verifier is useless, because the flow was started with the challenge created by your app and doesnt match to the verifier created by him.

Related to this question: Can't an attacker also get the code challenge?

What is PKCE trying to do?

like image 163
G-Unit Avatar answered May 22 '26 21:05

G-Unit