-
Notifications
You must be signed in to change notification settings - Fork 212
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
Allow no nonce option #434
Conversation
3bd6c56
to
d9d4e31
Compare
d9d4e31
to
647aaed
Compare
@@ -564,10 +564,6 @@ public function exchange() | |||
*/ | |||
public function renewTokens(array $options = []) | |||
{ | |||
if (! $this->accessToken) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no good reason I can think of to keep this check.
@@ -313,7 +294,7 @@ public function testThatRenewTokensSucceeds() | |||
|
|||
$mock = new MockHandler( [ | |||
// Code exchange response. | |||
new Response( 200, self::$headers, '{"access_token":"1.2.3","refresh_token":"2.3.4"}' ), | |||
new Response( 200, self::$headers, '{"access_token":"1.2.3","refresh_token":"2.3.4","id_token":"'.$id_token.'"}' ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The refresh token response would also omit an ID token if the original code exchange did not include one. Leaving this out makes this test inaccurate for how the process would work in a real application. With this ID token added, the nonce is checked and removed from storage before the tokens can be renewed. This then causes the exception that was reported in #432
src/Auth0.php
Outdated
]; | ||
|
||
$verifierOptions[self::TRANSIENT_NONCE_KEY] = $this->transientHandler->getOnce(self::TRANSIENT_NONCE_KEY); | ||
if (empty( $verifierOptions[self::TRANSIENT_NONCE_KEY] )) { | ||
if (false !== $verifierOptions[self::TRANSIENT_NONCE_KEY] && empty( $verifierOptions[self::TRANSIENT_NONCE_KEY] )) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting the nonce key to false
will now skip nonce checking in the ID token before setting.
@lbalmaceda - Adding you specifically since this is security-affecting. |
src/Auth0.php
Outdated
} | ||
|
||
$this->setAccessToken($response['access_token']); | ||
|
||
if (isset($response['id_token'])) { | ||
$this->setIdToken($response['id_token']); | ||
$this->setIdToken($response['id_token'], [self::TRANSIENT_NONCE_KEY => false]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The outer world should probably not know about the verification options.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few minor comments, nothing blocking. Ping me for the final approval
'leeway' => $this->idTokenLeeway, | ||
'max_age' => $this->transientHandler->getOnce('max_age') ?? $this->maxAge, | ||
self::TRANSIENT_NONCE_KEY => $this->transientHandler->getOnce(self::TRANSIENT_NONCE_KEY) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It makes sense for the storage to know the value is stored under the name of self::TRANSIENT_NONCE_KEY
. But this section on the left belongs to "verifierOptions". Do you need to use that name again or can you just use "nonce" here, knowing that that is what you are storing?
self::TRANSIENT_NONCE_KEY => $this->transientHandler->getOnce(self::TRANSIENT_NONCE_KEY) | |
'nonce' => $this->transientHandler->getOnce(self::TRANSIENT_NONCE_KEY) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That constant is just an enum so you don't have to remember the string.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's my point. For leeway
and max_age
you don't use any enum and still you're able to pick them up from the other side. It was a suggestion anyway 👍 the code works
* @throws ApiException | ||
* @throws CoreException | ||
*/ | ||
public function testThatExchangeFailsWithNoStoredNonce() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume this is the case because we don't allow to opt-out sending a nonce
during authentication?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Correct. Code exchange would only happen during login.
/** | ||
* @throws CoreException | ||
*/ | ||
public function testThatEmptyApplicationNonceFailsIdTokenValidation() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't this one be kept but with the condition/check inverted? e.g. id token validation when no nonce is stored should pass
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's handled in testThatRenewTokensSucceeds
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Description
Auth0->renewTokens()
to skip nonce checking for the ID tokenAuth0->renewTokens()
id_token
check fromAuth0->renewTokens()
responseTransientStoreHandler->isset()
to check for stored transient value without getting/deleting itReferences
Closes #432
Testing
647aaed - Fixes the renew token test to fail because of missing nonce, as it would (see issue above)