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

3

9

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?

Broken answered 4/2, 2021 at 9:41 Comment(0)
C
6

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 with the client secret at all.

Chandler answered 4/2, 2021 at 9:49 Comment(7)
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 tokenBroken
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 thisBroken
I wouldn't implement it my self if it is for production use, for production i would use 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.Chandler
the hardest lesson doing it yourself is that the code_verifier must be at least 43 characters long.See the spec at tools.ietf.org/html/rfc7636. Does this make my answer an acceptable answer?Chandler
It was acceptable from the beginning, thank youBroken
Is pkce the feature of oauth provider?Gardening
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.Chandler
G
6

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?

Graminivorous answered 5/2, 2021 at 11:40 Comment(3)
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 questionBroken
@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?Kelcy
What do you mean by saying "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"? Which client secret are you referring to? A public client does not maintain client secret at all, so there is no way an attacker can get it.Audette
P
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)

Pancratium answered 16/9, 2021 at 17:0 Comment(1)
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 itBroken

© 2022 - 2024 — McMap. All rights reserved.