Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Proof Key for Code Exchange (RFC 7636) #837

Closed
aadmathijssen opened this issue May 6, 2020 · 7 comments · Fixed by #901
Closed

Support Proof Key for Code Exchange (RFC 7636) #837

aadmathijssen opened this issue May 6, 2020 · 7 comments · Fixed by #901
Milestone

Comments

@aadmathijssen
Copy link

aadmathijssen commented May 6, 2020

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.

@ramsey
Copy link
Contributor

ramsey commented Oct 28, 2020

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

@ramsey ramsey changed the title Support for PKCE? Support Proof Key for Code Exchange (RFC 7636) Oct 28, 2020
@ramsey ramsey added this to the v3 milestone Oct 28, 2020
@D063520
Copy link

D063520 commented Nov 12, 2020

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

@ramsey
Copy link
Contributor

ramsey commented Nov 12, 2020

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

@rhertogh
Copy link
Contributor

@ramsey @D063520

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

Pull request is on it's way: #901

@rhertogh
Copy link
Contributor

@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.

@aadmathijssen
Copy link
Author

@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:

@rhertogh
Copy link
Contributor

rhertogh commented Aug 28, 2021

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants