oauth2-client icon indicating copy to clipboard operation
oauth2-client copied to clipboard

Support Proof Key for Code Exchange (RFC 7636)

Open aadmathijssen opened this issue 4 years ago • 7 comments

Hi,

It looks like the OAuth 2.0 client does not support Proof Key for Code Exchange (PKCE) for the Authorization Code flow. When looking through the code, I saw that the \League\OAuth2\Client\Provider\AbstractProvider::getAccessToken method always adds a client_secret parameter to the access token request. But for PKCE, I need to supply a code_verifier instead of a client_secret parameter.

Is this a missing feature from the library or am I missing something?

Thanks!

PS I am trying to use the OAuth 2.0 client in a PHP CLI application that should be rolled to multiple users. To avoid having the secret copied to all these instances, I intend to use PKCE.

aadmathijssen avatar May 06 '20 19:05 aadmathijssen

Reference: PKCE is Proof Key for Code Exchange. This is defined in RFC 7636.

ramsey avatar Oct 28 '20 18:10 ramsey

Hi,

thank you for providing the library and for maintaining it! We would like to use it in a scenario were PKCE is required .... I saw that you added this to v3. Could you give an estimate when you will have the time to implement this? Some month? a year?

Would really help : )

I would like to propose to make a pull request but I'm neither a php programmer nor an oAuth expert ; )

Salut D063520

D063520 avatar Nov 12 '20 11:11 D063520

@D063520, unfortunately, I have no estimate for this. No one is currently working on it, but we do welcome pull requests. 😃

ramsey avatar Nov 12 '20 15:11 ramsey

@ramsey @D063520

No one is currently working on it, but we do welcome pull requests. 😃

Pull request is on it's way: #901

rhertogh avatar Aug 16 '21 18:08 rhertogh

@aadmathijssen

PS I am trying to use the OAuth 2.0 client in a PHP CLI application that should be rolled to multiple users. To avoid having the secret copied to all these instances, I intend to use PKCE.

Not completely sure what your goal is, but PKCE is probably not what you are looking for. With PKCE a random code is generated at the client side. During the authorization request the code is hashed before sending. Later on, during the access token request the plain code is send along. This way the server can verify that the access token request originated from the same client that made the authorization request. It is not indented to identify the client itself. Swapping out the client_secret for a PKCE would leave your app very vulnerable for attacks.

rhertogh avatar Aug 16 '21 18:08 rhertogh

@rhertogh Thanks for the reply, although I don't think I understand it. My intention is to create a PHP CLI application that lets a user connect to the Microsoft Graph API to retrieve their own information. In order to authenticate the user, I want to use OAuth with PKCE. I can't see how this would leave my CLI application vulnerable for attacks.

The approach I intend to take is the same the as is described/implemented in the following:

  • https://kevcodez.de/posts/2020-06-07-pkce-oauth2-auth-flow-cli-desktop-app/
  • https://github.com/dogeared/pkce-cli

aadmathijssen avatar Aug 25 '21 19:08 aadmathijssen

@aadmathijssen

My warning was based on the remarks in the opening post, mainly:

... But for PKCE, I need to supply a code_verifier instead of a client_secret parameter. ... To avoid having the secret copied to all these instances, I intend to use PKCE. ...

This gave me the impression you are currently dealing with a "Confidential Client". If you would like to drop the client_secret your client would be a "Public Client". This itself has not much to do with PKCE, as it applies to both Public and Confidential clients (for an example attack on a Confidential client see OAuth 2.0 Auth Code Injection Attack in Action). Hence, "PKCE is required for all OAuth clients using the authorization code flow" in OAuth 2.1.

Without client authentication the Authorization Server cannot fully verify the client's identity. For a Public Client the only validation the Authorization Server can apply is validating the Redirect URI of the client. Usually the includes the domain name, but since your application runs locally on the command line the Redirect URI would most likely be localhost, further increasing the attack surface (any application listening locally could retrieve a valid Authorization Code).

To address the link you mentioned:

TLDR: The PKCE flow is a secure way to authenticate public clients.

That statement is incorrect and based on a common misconception. It should have been "The PKCE flow is a more secure way to exchange an authorization_code for an access_token". More secure than without PKCE, but not a replacement for a Confidential Client since it does not authenticate public clients. A good article addressing this Client Authentication vs. PKCE: Do you need both?

So unless the Client Secret cannot be stored securely by the client, you probably want to use a Confidential Client in combination with PKCE. Only if the client can not store the Client Secret securely (e.g. in case of a browser based application/Native mobile app) a Public Client in combination with PKCE could be used.

rhertogh avatar Aug 28 '21 14:08 rhertogh