matomo-org / matomo-org/plugin-OAuth2

Security: delete OAuth token families when their Matomo user is deleted

Open
#39 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
PHP
Stars
0
Forks
2
Avg merge
23h 49m
Merged PRs (30d)
9

Description

Security issue

OAuth2 access tokens, refresh tokens, and authorization codes are not revoked when their subject Matomo user is deleted.

The plugin stores the token subject using the reusable textual user_login. If that login is later assigned to a different user, an unexpired token family belonging to the deleted user can authenticate as the replacement account and inherit that account’s current Matomo permissions.

Observed lifecycle
  1. User A authorizes an OAuth client and receives an access/refresh token pair.
  2. An administrator deletes user A.
  3. The OAuth token and refresh-token rows remain active and unrevoked.
  4. The refresh endpoint still accepts A’s refresh token while no user exists for its subject.
  5. A different user B is later created with the same Matomo login.
  6. A bearer issued from A’s old refresh-token family is then resolved as user B and receives B’s current site access.

A different-login user does not activate the token. The reactivation occurs specifically because OAuth2 binds the token subject to the reusable login string rather than an immutable user identity.

Security impact

A former user or previously authorized OAuth client that retains an unexpired refresh token may later authenticate as a different person if an administrator reuses the same Matomo login.

The stale token receives the replacement user’s current permissions, potentially exposing private site metadata and reporting data that the original user was never authorized to access.

For confidential OAuth clients, the holder also needs the client credentials previously issued to that client.

Root cause

The OAuth2 plugin does not subscribe to Matomo’s user-deletion event and does not revoke token data associated with the deleted login.

The affected design includes:

  • access-token subjects stored using user_login;
  • refresh-token families surviving user deletion;
  • refresh grants not checking whether the original subject still exists;
  • resource-server authentication resolving the JWT login against the current Matomo user row;
  • no immutable user ID or account-generation identifier in the token lineage.
Suggested fix

Please:

  1. Subscribe to the relevant user-deletion event, such as UsersManager.deleteUser, and revoke or delete all access tokens, refresh tokens, and authorization codes belonging to the deleted user.
  2. Reject refresh-token exchanges when the original token subject no longer exists.
  3. Bind OAuth subjects to an immutable user ID or identity-generation value rather than only the reusable login string.
  4. Verify that immutable identifier during both token refresh and resource-server authentication.
  5. Add a regression test covering:
authorize as user A
→ delete user A
→ attempt refresh
→ recreate the same login as user B
→ confirm every token issued to A remains invalid

This would prevent credentials belonging to one identity generation from being rebound to a later user who happens to receive the same login.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by tracing the OAuth2 plugin's handling of the UsersManager.deleteUser event, token storage, refresh grants, and resource-server authentication. Review how subjects use user_login and identify the relevant token records and validation paths. Done means the described delete, refresh, same-login recreation sequence leaves every token from the deleted user invalid, with a regression test covering it.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
authentication, backend, security
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.