Page MenuHomePhabricator

Lcobucci\JWT\Signer\InvalidKeyProvided: Key cannot be empty (/w/rest.php/oauth2/access_token)
Closed, ResolvedPublicPRODUCTION ERROR

Description

Error
  • service.version: 1.46.0-wmf.14
  • timestamp: 2026-02-04T10:27:30.342Z
  • labels.phpversion: 8.3.30
  • trace.id: 171cd142-245e-469c-b740-485a309e00d4
  • Find trace.id in Logstash
labels.normalized_message
[{reqId}] {exception_url}   Lcobucci\JWT\Signer\InvalidKeyProvided: Key cannot be empty
FrameLocationCall
from/srv/mediawiki/php-1.46.0-wmf.14/vendor/lcobucci/jwt/src/Signer/InvalidKeyProvided.php(34)
#0/srv/mediawiki/php-1.46.0-wmf.14/vendor/lcobucci/jwt/src/Signer/Key/InMemory.php(25)Lcobucci\JWT\Signer\InvalidKeyProvided::cannotBeEmpty()
#1/srv/mediawiki/php-1.46.0-wmf.14/vendor/lcobucci/jwt/src/Signer/Key/InMemory.php(45)Lcobucci\JWT\Signer\Key\InMemory->__construct(string, string)
#2/srv/mediawiki/php-1.46.0-wmf.14/extensions/OAuth/src/Entity/AccessTokenEntity.php(95)Lcobucci\JWT\Signer\Key\InMemory::plainText(string)
#3/srv/mediawiki/php-1.46.0-wmf.14/vendor/league/oauth2-server/src/Grant/AbstractGrant.php(455)MediaWiki\Extension\OAuth\Entity\AccessTokenEntity->setPrivateKey(League\OAuth2\Server\CryptKey)
#4/srv/mediawiki/php-1.46.0-wmf.14/vendor/league/oauth2-server/src/Grant/ClientCredentialsGrant.php(58)League\OAuth2\Server\Grant\AbstractGrant->issueAccessToken(DateInterval, MediaWiki\Extension\OAuth\Entity\ClientEntity, null, array, array)
#5/srv/mediawiki/php-1.46.0-wmf.14/vendor/league/oauth2-server/src/AuthorizationServer.php(205)League\OAuth2\Server\Grant\ClientCredentialsGrant->respondToAccessTokenRequest(GuzzleHttp\Psr7\ServerRequest, League\OAuth2\Server\ResponseTypes\BearerTokenResponse, DateInterval)
#6/srv/mediawiki/php-1.46.0-wmf.14/extensions/OAuth/src/AuthorizationProvider/AccessToken.php(22)League\OAuth2\Server\AuthorizationServer->respondToAccessTokenRequest(GuzzleHttp\Psr7\ServerRequest, MediaWiki\Extension\OAuth\Response)
#7/srv/mediawiki/php-1.46.0-wmf.14/extensions/OAuth/src/Rest/Handler/AccessToken.php(50)MediaWiki\Extension\OAuth\AuthorizationProvider\AccessToken->getAccessTokens(GuzzleHttp\Psr7\ServerRequest, MediaWiki\Extension\OAuth\Response)
#8/srv/mediawiki/php-1.46.0-wmf.14/includes/Rest/Module/Module.php(472)MediaWiki\Extension\OAuth\Rest\Handler\AccessToken->execute()
#9/srv/mediawiki/php-1.46.0-wmf.14/includes/Rest/Module/Module.php(301)MediaWiki\Rest\Module\Module->executeHandler(MediaWiki\Extension\OAuth\Rest\Handler\AccessToken)
#10/srv/mediawiki/php-1.46.0-wmf.14/includes/Rest/Router.php(484)MediaWiki\Rest\Module\Module->execute(string, MediaWiki\Rest\RequestFromGlobals)
#11/srv/mediawiki/php-1.46.0-wmf.14/includes/Rest/Router.php(443)MediaWiki\Rest\Router->doExecute(string, MediaWiki\Rest\RequestFromGlobals)
#12/srv/mediawiki/php-1.46.0-wmf.14/includes/Rest/EntryPoint.php(181)MediaWiki\Rest\Router->execute(MediaWiki\Rest\RequestFromGlobals)
#13/srv/mediawiki/php-1.46.0-wmf.14/includes/MediaWikiEntryPoint.php(180)MediaWiki\Rest\EntryPoint->execute()
#14/srv/mediawiki/php-1.46.0-wmf.14/rest.php(25)MediaWiki\MediaWikiEntryPoint->run()
#15/srv/mediawiki/w/rest.php(3)require(string)
#16{main}
Impact
Notes

Event Timeline

hashar triaged this task as Unbreak Now! priority.
Restricted Application added a subscriber: Aklapper. · View Herald Transcript

OAuth did not get much update

$ git -C mediawiki/extensions/OAuth releasenotes origin/wmf/1.46.0-wmf.13..origin/wmf/1.46.0-wmf.14
[BOT] Translation updater bot (3):
      * [6adb9e8f] Localisation updates from https://translatewiki.net.
      * [00f9b57f] Localisation updates from https://translatewiki.net.
      * [9abf4346] Localisation updates from https://translatewiki.net.

[BOT] libraryupgrader (1):
      * [0e9fbc22] build: Updating lodash to 4.17.23

vendor

$ git -C mediawiki/vendor releasenotes origin/wmf/1.46.0-wmf.13..origin/wmf/1.46.0-wmf.14
Alexander Vorwerk (1):
      * [a873440de] Updated wikimedia/ip-utils from 6.0.0 to 6.0.1

C. Scott Ananian (2):
      * [10feea1d4] Bump wikimedia/parsoid to 0.23.0-a13.1
      * [ae85df514] Bump wikimedia/parsoid to 0.23.0-a14

Sam Reed (7):
      * [604513e51] Upgrade symfony/*
      * [1b9df20ea] Upgrading psy/psysh (v0.12.10 => v0.12.19)
      * [5e725644e] Upgrading web-auth/cose-lib (4.4.2 => 4.5.0)
      * [4ddd548ec] Upgrading brick/math (0.13.1 => 0.14.2)
      * [abedb5d13] Upgrading lcobucci/jwt (4.1.5 => 4.3.0)
      * [4acc02da3] Add webonyx/graphql-php (v15.30.0)
      * [15d8c7295] Upgrading webonyx/graphql-php (v15.30.0 => v15.30.1)

So that would be caused by abedb5d13 Upgrading lcobucci/jwt (4.1.5 => 4.3.0)? https://gerrit.wikimedia.org/r/c/mediawiki/vendor/+/1235417 / https://gerrit.wikimedia.org/r/c/mediawiki/core/+/1235513 . Which seems to be part of a routine update of libraries.

https://github.com/lcobucci/jwt/releases/tag/4.3.0 states:

*Improvement*

938: Deprecate empty Signer, empty Key and empty Signature thanks to @Slamdunk

From the pull request:

This PR deprecates:

Lcobucci\JWT\Signer\None
\Lcobucci\JWT\Signer\Key\InMemory::empty
\Lcobucci\JWT\Token\Signature::fromEmptyData
and as a result, \Lcobucci\JWT\Configuration::forUnsecuredSigner

And surely the update did:

diff --git a/lcobucci/jwt/src/Signer/Key/InMemory.php b/lcobucci/jwt/src/Signer/Key/InMemory.php
index 1a4df0f58..1a12e01a3 100644
--- a/lcobucci/jwt/src/Signer/Key/InMemory.php
+++ b/lcobucci/jwt/src/Signer/Key/InMemory.php
@@ -3,6 +3,7 @@ declare(strict_types=1);
 
 namespace Lcobucci\JWT\Signer\Key;
 
+use Lcobucci\JWT\Signer\InvalidKeyProvided;
 use Lcobucci\JWT\Signer\Key;
 use Lcobucci\JWT\SodiumBase64Polyfill;
 use SplFileObject;
@@ -16,22 +17,35 @@ final class InMemory implements Key
     private string $contents;
     private string $passphrase;
 
+    /** @param non-empty-string $contents */
     private function __construct(string $contents, string $passphrase)
     {
+        // @phpstan-ignore-next-line
+        if ($contents === '') {
+            throw InvalidKeyProvided::cannotBeEmpty();
+        }
+

The upgrade of lcobucci/jwt (4.1.5 => 4.3.0) is a breaking change for OAuth. That was introduced by https://gerrit.wikimedia.org/r/c/mediawiki/vendor/+/1235417 / https://gerrit.wikimedia.org/r/c/mediawiki/core/+/1235513 and I don't quite know anymore how to rollback changes to vendor / composer.json :-/

Change #1236691 had a related patch set uploaded (by Zabe; author: Zabe):

[mediawiki/core@master] Revert "Updated lcobucci/jwt from 4.1.5 to 4.3.0"

https://gerrit.wikimedia.org/r/1236691

Change #1236692 had a related patch set uploaded (by Zabe; author: Zabe):

[mediawiki/core@wmf/1.46.0-wmf.14] Revert "Updated lcobucci/jwt from 4.1.5 to 4.3.0"

https://gerrit.wikimedia.org/r/1236692

Change #1236693 had a related patch set uploaded (by Zabe; author: Zabe):

[mediawiki/vendor@wmf/1.46.0-wmf.14] Revert "Updated lcobucci/jwt from 4.1.5 to 4.3.0"

https://gerrit.wikimedia.org/r/1236693

The upgrade of lcobucci/jwt (4.1.5 => 4.3.0) is a breaking change for OAuth. That was introduced by https://gerrit.wikimedia.org/r/c/mediawiki/vendor/+/1235417 / https://gerrit.wikimedia.org/r/c/mediawiki/core/+/1235513 and I don't quite know anymore how to rollback changes to vendor / composer.json :-/

I uploaded reverts for wmf.14 above, but I think we should OAuth passing an empty string on master instead.

@hashar do you have a plan on how to tackle this? just a quick rollback of the version or do you prefer to fix the code ASAP? Definitely we should fix and update the lib, I'm just not sure about timing.

Ok, to follow-up - this looks like a simple fix without having to revert the library - this was introduced in https://gerrit.wikimedia.org/r/c/mediawiki/extensions/OAuth/+/1198714/7/src/Entity/AccessTokenEntity.php - and are directly passing an empty string as the key. It seems like we could just change that line and get it working but I'm not sure what would be the outcome of such change.

@Tgr can you explain why are we passing an empty string there? Can we change it to for example OAuthExtension ?

Tgr lowered the priority of this task from Unbreak Now! to Needs Triage.Wed, Feb 4, 11:14 AM
Tgr set Security to Software security bug.
Tgr added projects: Security, Security-Team.
Tgr changed the visibility from "Public (No Login Required)" to "Custom Policy".
Tgr changed the subtype of this task from "Production Error" to "Security Issue".

Let's mark this as a security issue just in case. Using an empty key seems bad.

Never mind, I was looking at the wrong place. Not a security issue.

pmiazga triaged this task as Unbreak Now! priority.Wed, Feb 4, 11:19 AM

I think it has to stay Unbreak Now as it's a train blocker atm

taavi changed the visibility from "Custom Policy" to "Public (No Login Required)".Wed, Feb 4, 11:29 AM
taavi changed the subtype of this task from "Security Issue" to "Production Error".

Change #1236697 abandoned by Gergő Tisza:

[mediawiki/extensions/OAuth@master] Do not use an empty key

Reason:

doesn't help, some of the empty key usage is in the oauth2-server library

https://gerrit.wikimedia.org/r/1236697

BearerTokenValidator::initJwtConfiguration() in the league/oauth2-server library also calls InMemory::plainText('').

We'll need to revert the lcobucci/jwt version bump and coordinate the upgrades of the two libraries.

I am going to try to revert the vendor patch, and that reminds me I should probably finally test core/vendor/CentralAuth together (T333541).

Change #1236715 had a related patch set uploaded (by Hashar; author: Hashar):

[mediawiki/vendor@master] Revert "Upgrading lcobucci/jwt (4.1.5 => 4.3.0)"

https://gerrit.wikimedia.org/r/1236715

Change #1236727 had a related patch set uploaded (by Hashar; author: Hashar):

[mediawiki/core@master] Revert "Updated lcobucci/jwt from 4.1.5 to 4.3.0"

https://gerrit.wikimedia.org/r/1236727

I have created the revert for the master branch:

mediawiki/vendorGerrit 1236715
mediawiki/coreGerrit 1236727

For the backports to wmf/1.46.0-wmf.14 branch we gotta hold for the changes to be merged in master. The reason is the changes created by the cherry-pick in Gerrit would have the same Change-Id header. There will be thus two vendor patches depended on by the mediawiki/core patch and CI will never process it. That is merely paper work :]

@Zabe has sent the backports with different Change-Id:

https://gerrit.wikimedia.org/r/c/mediawiki/vendor/+/1236693
https://gerrit.wikimedia.org/r/c/mediawiki/core/+/1236692

brennen moved this task from Backlog to Logs/Train on the User-brennen board.
brennen subscribed.

Change #1236693 merged by jenkins-bot:

[mediawiki/vendor@wmf/1.46.0-wmf.14] Revert "Updated lcobucci/jwt from 4.1.5 to 4.3.0"

https://gerrit.wikimedia.org/r/1236693

Change #1236692 merged by jenkins-bot:

[mediawiki/core@wmf/1.46.0-wmf.14] Revert "Updated lcobucci/jwt from 4.1.5 to 4.3.0"

https://gerrit.wikimedia.org/r/1236692

Mentioned in SAL (#wikimedia-operations) [2026-02-05T00:30:02Z] <reedy@deploy2002> Started scap sync-world: Backport for [[gerrit:1236692|Revert "Updated lcobucci/jwt from 4.1.5 to 4.3.0" (T416456)]], [[gerrit:1236693|Revert "Updated lcobucci/jwt from 4.1.5 to 4.3.0" (T416456)]]

Mentioned in SAL (#wikimedia-operations) [2026-02-05T00:32:16Z] <reedy@deploy2002> reedy, zabe: Backport for [[gerrit:1236692|Revert "Updated lcobucci/jwt from 4.1.5 to 4.3.0" (T416456)]], [[gerrit:1236693|Revert "Updated lcobucci/jwt from 4.1.5 to 4.3.0" (T416456)]] synced to the testservers (see https://wikitech.wikimedia.org/wiki/Mwdebug). Changes can now be verified there.

Mentioned in SAL (#wikimedia-operations) [2026-02-05T00:36:52Z] <reedy@deploy2002> Finished scap sync-world: Backport for [[gerrit:1236692|Revert "Updated lcobucci/jwt from 4.1.5 to 4.3.0" (T416456)]], [[gerrit:1236693|Revert "Updated lcobucci/jwt from 4.1.5 to 4.3.0" (T416456)]] (duration: 06m 50s)

Change #1236715 merged by jenkins-bot:

[mediawiki/vendor@master] Revert "Upgrading lcobucci/jwt (4.1.5 => 4.3.0)"

https://gerrit.wikimedia.org/r/1236715

Change #1236727 merged by jenkins-bot:

[mediawiki/core@master] Revert "Updated lcobucci/jwt from 4.1.5 to 4.3.0"

https://gerrit.wikimedia.org/r/1236727

hashar claimed this task.

The rollback patches got backported by @Zabe and approved by @Reedy (thank you both!).

There is a follow up task filed to document reverting mediawiki/vendor, I imagine we might want one to upgrade lcobucci/jwt and adjust OAuth. Meanwhile the immediate issue has been resolved and it is not more blocking the train.