4

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?

Mehdi Amenein
  • 937
  • 9
  • 23

3 Answers3

3

PKCE is all about verifying that the client that initiated the initial authentication request is also the same that uses the authorization code to get the real tokens.

PKCE is a protection check that is implemented on the Identity Provider side, compared to the State/Nonce security features that requires the client to do the checks.

PKCE has nothing to do wit the client secret at all.

Tore Nestenius
  • 16,431
  • 5
  • 30
  • 40
  • Thank you for the answer, I know it has nothing to do with the client_secret I am trying to understand the security comparison between these 2, I was not sure what the purpose of using it was, so it basically is not related to the Cross-domain or similar attacks, we just validate that the same user who authorized is issuing a token – Mehdi Amenein Feb 04 '21 at 09:55
  • Is there any best practice article that you can recommend to me for the implementation of this? Cause during my tests I was storing both Verifier and Code_challenge in the local storage temporarily until the token was being generated and I am sure there are better alternatives to this – Mehdi Amenein Feb 04 '21 at 09:59
  • 2
    I wouldn't implement it my self if it is for production use, for production i would use https://github.com/IdentityModel/oidc-client-js or similar ready made libraries. PKCE is not that hard to implement yourself. You only need to store the Verifier, perhaps in a cookie or local storage. – Tore Nestenius Feb 04 '21 at 10:18
  • the hardest lesson doing it yourself is that the code_verifier must be at least 43 characters long.See the spec at https://tools.ietf.org/html/rfc7636. Does this make my answer an acceptable answer? – Tore Nestenius Feb 04 '21 at 10:19
  • It was acceptable from the beginning, thank you – Mehdi Amenein Feb 04 '21 at 10:31
  • Is pkce the feature of oauth provider? – variable Feb 05 '22 at 12:23
  • PKCE is a feature that both the client and the provider needs to support to fully function. PKCE is validated on the server, compared to the nonce that is validated on the client. So If the provider requires it, then the client must provide the PKCE values in the authentication process. – Tore Nestenius Feb 05 '22 at 13:43
3

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?

Boommeister
  • 1,591
  • 2
  • 15
  • 54
  • Thank you for your detailed explanation, I went through a couple of more articles yesterday and now am using PKCE as it really makes more scene. But your explanation actually summarized the whole thing in a very straightforward manner and sharing articles hope it also be helpful to others who might cross this question – Mehdi Amenein Feb 05 '21 at 11:52
  • @Boommeister, thank you for your explanation! Another question, if the attacker managed to make the user use his version of the app, is there any other mechanism to prevent the access token from being issued to it? – Jeff Tian May 10 '23 at 04:16
0

It is not. Auth code with PKCE is only more secure than the implicit flow, which does not involve a client secret.

PKCE is a way to implement the more secure authorisation code flow (which needs a client secret otherwise)

Himanshu Arora
  • 2,368
  • 3
  • 22
  • 33
  • Hey sorry for the delay in response, We are currently doing a Backend For Frontend and there we are using client secrets but at the same time send challenge and verify it – Mehdi Amenein Oct 05 '21 at 07:17