element-hq / element-hq/synapse

[Synapse Module] user_may_join_room callback function should be by-passed for server admin requesters

Open
#19,364 0 comments 0 reactions 0 assignees View on GitHub
A-Admin-API A-Modules O-Occasional S-Minor T-Defect
Dominant language
Python
Stars
4.6k
Forks
600
Avg merge
5d 22h
Merged PRs (30d)
51

Description

### Description

A Synapse Admin API allows to force users to join a room => https://element-hq.github.io/synapse/latest/admin_api/room_membership.html.
A call to this API should not be intercepted by the `user_may_join_room callback` function, as the requester is necessarily a server administrator. This is clearly stated in the callback documentation (https://element-hq.github.io/synapse/latest/modules/spam_checker_callbacks.html#user_may_join_room):

> This callback isn't called if the join is performed by a server administrator, or in the context of a room creation

However, after some testing, it appears that this callback does in fact intercept this API call.

After a discussion with @anoadragon453 (many thanks for your help) in the Synapse Development room, the following points were raised:
- The implementation of the Admin API creates a "fake requester" (see https://github.com/element-hq/synapse/blob/f4320b5a4926a8f5b7fb7d6899a22f7dc7236114/synapse/rest/admin/rooms.py#L583-L585) masquerading the target user, then execute the membership change. So the spam checker code has no idea an admin originated the request
- The following ideas were proposed to solve the problem:
- First idea : the Admin API can check the original user via the authenticated_entity attribute of the requester. So the admin check should be updated to check requester.authenticated_entity instead, if set (could be a bit complicated when taking MAS support into account?)
- Second idea : make a v2 of the `user_may_join_room` callback function that passes both the target User ID and the requester (this way module code can check if requester is a server admin or not and bypass the function if needed)

### Steps to reproduce

- Add a Synapse module implementing `user_may_join_room` callback function to your homeserver
- Call "Edit Room Membership API" (see https://element-hq.github.io/synapse/latest/admin_api/room_membership.html) with a server admin access token
- The Synapse module and its `user_may_join_room` callback function should not be called as the requester is a server admin, but they are

### Homeserver

Another private homeserver

### Synapse Version

1.144.0

### Installation Method

pip (from PyPI)

### Database

Single PostgreSQL server (PostgreSQL 17.6 on amd64-portbld-freebsd14.3, compiled by clang version 19.1.7, 64-bit), no usage of "portdb" script, no backup restore

### Workers

Single process

### Platform

Synapse runs in a virtual machine equipped with Debian GNU/Linux 12 (Bookworm).

### Configuration

We use Synapse modules, no other "unusual config options".

### Relevant log output

```shell
The only output we have is our module's log, which we should not see.
```

### Anything else that would be useful to know?

_No response_

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.