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

Validate confidential clients and determine if the client handles the grant type #1420

Open
wants to merge 12 commits into
base: master
Choose a base branch
from

Conversation

hafezdivandari
Copy link
Contributor

@hafezdivandari hafezdivandari commented Jun 30, 2024

Fixes #1174
Fixes #1369
Fixes #1073
Closes #1036

This PR can be considered as a security enhancement and does 2 main changes:

  1. Validate confidential clients:
  2. New ClientEntityInterface::hasGrantType() function:
    • RFC6749 section 5.2
    • Fixes Add Unauthorized_Client support #1174
    • This function is implemented on ClientTrait that returns true by default to avoid BC breaking changes.
    • Currently there is no way to check if the client handles the grant type before proceeding the request, e.g. We don't want to make auth code on "auth code grant" or make device code on "device code auth" grant or response with the access token on "implicit token" grant if the specified client doesn't handle the grant type. This PR makes this possible to avoid handling the requested grant type if the specified client doesn't supports that.
    • It also makes it possible for us to disable issuing refresh token if the client doesn't handle this grant.

@hafezdivandari hafezdivandari changed the title Always validate client Always validate the client and determine if it handles the grant type Oct 1, 2024
@hafezdivandari hafezdivandari mentioned this pull request Oct 10, 2024
8 tasks
@hafezdivandari hafezdivandari changed the title Always validate the client and determine if it handles the grant type Validate confidential clients and determine if the client handles the grant type Oct 18, 2024
@@ -38,4 +38,9 @@ public function getRedirectUri(): string|array;
* Returns true if the client is confidential.
*/
public function isConfidential(): bool;

/**
* Returns true if the client handles the given grant type.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a grant type settings. Otherwise the client must know about all grant types.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, the client may know the grant types it can handle, for example by having grant_types according to RFC7591

Copy link
Contributor

@eugene-borovov eugene-borovov Nov 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RFC7591 describes the proccess of filling the client repository. It responses with a client information record. ClientRepositoryInterface has validateClient($clientIdentifier, $clientSecret, $grantType) method. The client's support for the grant type should be done in this method. Do you agree with it?

Copy link
Contributor Author

@hafezdivandari hafezdivandari Nov 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RFC7591 describes the proccess of filling the client repository. It responses with a client information record

It was just an example of how client may define its supported grant types.

ClientRepositoryInterface has validateClient($clientIdentifier, $clientSecret, $grantType) method. The client's support for the grant type should be done in this method. Do you agree with it?

That's exactly what I don't agree with in the current implementation, and this PR tries to fix.

First of all, this method returns bool, and causes invalid_client error when it returns false, but we need unauthorized_client error, when the client doesn't support the given grant type.

Second this method (validateClient) main intention is to validate the client secret, you may check its description.

Third, this method is being called too late, in the last step of the flow, on respondToAccessTokenRequest method of all grants. But we want to check if the client actually handles the grant type in the very beginning of the flow.

Lets assume we have a client that only supports client_credentials grant, currently you can use this client to get an authorization code with no problem, and then in the last step when you want to use that code to get an access_token the server calls validateClient method, and you'll get invalid_client error. After this PR, you will get unauthorized_client error, in the first step, when you want to use that client to get an authorization code, because this client doesn't actually handle "authorization code" grant but only "client credentials" grant.

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