Skip to content

Commit

Permalink
Ensure leaving the channel and rejoining doesn't allow you to quote-r…
Browse files Browse the repository at this point in the history
…eply messages you haven't seen
  • Loading branch information
tadzik committed Mar 26, 2024
1 parent df04ed8 commit ffcba6f
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 2 deletions.
49 changes: 49 additions & 0 deletions spec/e2e/replies.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,4 +135,53 @@ describe('Reply handling', () => {
const postRestartCharlieMsgBody = (await postRestartCharlieMsg)[2];
expect(postRestartCharlieMsgBody).toContain(postRestartAliceMsgBody);
});

it('should not leak the contents of messages to leavers', async () => {
await setupTestEnv(0);

const channel = `#${TestIrcServer.generateUniqueNick("test")}`;
const { homeserver, ircBridge } = testEnv;
const [alice, charlie] = homeserver.users.map(u => u.client);
const { bob } = testEnv.ircTest.clients;

// Create the channel
await bob.join(channel);

const adminRoomId = await testEnv.createAdminRoomHelper(alice);
const cRoomId = await testEnv.joinChannelHelper(alice, adminRoomId, channel);
const roomName = await alice.getRoomStateEvent(cRoomId, 'm.room.name', '');
expect(roomName.name).toEqual(channel);

const bobUserId = `@irc_${bob.nick}:${homeserver.domain}`;
await alice.waitForRoomEvent(
{eventType: 'm.room.member', sender: bobUserId, stateKey: bobUserId, roomId: cRoomId}
);

await charlie.joinRoom(cRoomId);
await charlie.leaveRoom(cRoomId);

// Send some messages
const aliceMsg = bob.waitForEvent('message', 10000);
const bobMsg = alice.waitForRoomEvent(
{eventType: 'm.room.message', sender: bobUserId, roomId: cRoomId}
);
const aliceMsgBody = "Hello bib!";
const aliceEventId = alice.sendText(cRoomId, aliceMsgBody);
await aliceMsg;
bob.say(channel, "Hi alice!");
await bobMsg;

// Now charlie joins and tries to reply to alice.
await charlie.joinRoom(cRoomId);
const charlieMsgIrcPromise = bob.waitForEvent('message', 10000);
await charlie.replyText(cRoomId, {
event_id: await aliceEventId,
}, "Sneaky reply to a message I have not seen");

// Safety check to ensure that we're using the long form reply format.
expect(ircBridge.config.ircService.matrixHandler?.shortReplyTresholdSeconds).toBe(0);
// The long form reply format should not contain alice's message.
const charlieIrcMessage = (await charlieMsgIrcPromise)[2];
expect(charlieIrcMessage).not.toContain(aliceMsgBody);
});
});
6 changes: 4 additions & 2 deletions src/bridge/MatrixHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -393,8 +393,10 @@ export class MatrixHandler {
* @param {Object} event : The Matrix member event.
*/
private _onMemberEvent(req: BridgeRequest, event: OnMemberEventData) {
if (event.origin_server_ts) {
this.memberJoinTs.set(`${event.room_id}/${event.state_key}`, event.origin_server_ts);
if (event.content.membership === 'join') {
this.memberJoinTs.set(`${event.room_id}/${event.state_key}`, event.origin_server_ts ?? Date.now());
} else {
this.memberJoinTs.delete(`${event.room_id}/${event.state_key}`);
}
this.memberTracker?.onEvent(event);
}
Expand Down

0 comments on commit ffcba6f

Please sign in to comment.