fix: verify the oauth2 state before the error parameter

This commit is contained in:
2026-09-23 17:48:24 +02:00
parent 3f4586ce06
commit f48e53fdd0
2 changed files with 46 additions and 23 deletions
+20 -1
View File
@@ -32,7 +32,7 @@ class MyEpClientTest extends TestCase
// the challenge is what MyE&P stores; the verifier replayed on the token request
// has to hash to it, or the exchange is refused
$expectedChallenge = trim(strtr(base64_encode(hash('sha256', $verifier, true)), '+/', '-_'), '=');
$expectedChallenge = rtrim(strtr(base64_encode(hash('sha256', $verifier, true)), '+/', '-_'), '=');
$this->assertSame($expectedChallenge, $query['code_challenge']);
}
@@ -59,6 +59,25 @@ class MyEpClientTest extends TestCase
$this->assertFalse($request->getSession()->has('oauth2pkce'));
}
public function testDeniedCallbackWithAForeignStateIsRefusedAsAMismatch(): void
{
$request = $this->createRequest([
'state' => 'other-state',
'error' => 'access_denied',
]);
$request->getSession()->set('oauth2state', 'expected-state');
$request->getSession()->set('oauth2pkce', 'verifier');
// the state is checked before the error parameter: a callback that cannot prove it
// belongs to this flow must not be able to report a denial into it. Otherwise a
// link to this route would consume the pending state of whoever follows it - the
// session cookie is SameSite=lax, so it rides along on a top-level navigation.
$this->expectException(AuthorizationRequestException::class);
$this->expectExceptionMessage('Missing state or mismatch');
$this->createClient()->fetchAccessToken($request);
}
public function testCallbackIsRefusedWhenTheSessionHoldsNoVerifier(): void
{
$request = $this->createRequest(['code' => 'a-code', 'state' => 'expected-state']);