@@ -43,11 +43,29 @@ public function parseAndVerify(string $jwt): UnencryptedToken
4343
4444 $ data = $ this ->loadKeys ();
4545
46- $ publicKeys = JWK ::parseKeySet ($ data );
46+ /**
47+ * This is kind of jank, but the `alg` claim in the JWK is not required by the spec, so Microsoft has opted
48+ * not to include it.
49+ *
50+ * As of v6, the JWT library requires either the alg to be provided -or- a default given, to mitigate
51+ * CVE-2021-46743, a key type confusion attack. The CVE is probably broadly applicable to any implementation
52+ * dealing with these keys missing their `alg` claims.
53+ *
54+ * If Microsoft updates in the future, they will hopefully start providing the `alg` claim on the new keys in
55+ * the keyring. In that case, this will continue to work just fine, since the `alg` claim has priority over
56+ * this default.
57+ *
58+ * @see https://github.com/firebase/php-jwt/issues/498
59+ * @see https://github.com/advisories/GHSA-8xf4-w7qw-pjjw
60+ * @see https://github.com/firebase/php-jwt/issues/351
61+ */
62+ $ defaultAlgorithm = 'RS256 ' ;
63+
64+ $ publicKeys = JWK ::parseKeySet ($ data , $ defaultAlgorithm );
4765 $ kid = $ token ->headers ()->get ('kid ' );
4866
4967 if (isset ($ publicKeys [$ kid ])) {
50- $ publicKey = openssl_pkey_get_details ($ publicKeys [$ kid ]);
68+ $ publicKey = openssl_pkey_get_details ($ publicKeys [$ kid ]-> getKeyMaterial () );
5169 $ constraints = [
5270 new SignedWith (new Sha256 (), InMemory::plainText ($ publicKey ['key ' ])),
5371 new LooseValidAt (SystemClock::fromSystemTimezone ()),
0 commit comments