MM-67279: Fix private channel enumeration via /mute slash command (#35099)

* MM-67279: Fix private channel enumeration via /mute slash command

Return the same error message when a user tries to mute a channel
they are not a member of as when the channel doesn't exist. This
prevents authenticated users from discovering private channels
by observing different error responses.

* update i18n

---------

Co-authored-by: Mattermost Build <build@mattermost.com>
This commit is contained in:
Jesse Hallam
2026-01-30 14:43:23 +00:00
committed by GitHub
co-authored by Mattermost Build
parent 90bdd6ae54
commit 5bb5261c72
3 changed files with 4 additions and 7 deletions
@@ -64,7 +64,7 @@ func (*MuteProvider) DoCommand(a *app.App, rctx request.CTX, args *model.Command
channelMember, err := a.ToggleMuteChannel(rctx, channel.Id, args.UserId)
if err != nil {
return &model.CommandResponse{Text: args.T("api.command_mute.not_member.error", map[string]any{"Channel": channelName}), ResponseType: model.CommandResponseTypeEphemeral}
return &model.CommandResponse{Text: args.T("api.command_mute.error", map[string]any{"Channel": channelName}), ResponseType: model.CommandResponseTypeEphemeral}
}
// Direct and Group messages won't have a nice channel title, omit it
@@ -130,13 +130,14 @@ func TestMuteCommandNotMember(t *testing.T) {
cmd := &MuteProvider{}
// First mute the channel
// Muting a channel that the user is not a member of should return
// the same error as a non-existent channel to prevent channel enumeration
resp := cmd.DoCommand(th.App, th.Context, &model.CommandArgs{
T: i18n.IdentityTfunc(),
ChannelId: channel1.Id,
UserId: th.BasicUser.Id,
}, channel2.Name)
assert.Equal(t, "api.command_mute.not_member.error", resp.Text)
assert.Equal(t, "api.command_mute.error", resp.Text)
}
func TestMuteCommandNotChannel(t *testing.T) {
-4
View File
@@ -1261,10 +1261,6 @@
"id": "api.command_mute.no_channel.error",
"translation": "Could not find the specified channel. Please use the [channel handle](https://docs.mattermost.com/messaging/managing-channels.html#naming-a-channel) to identify channels."
},
{
"id": "api.command_mute.not_member.error",
"translation": "Could not mute channel {{.Channel}} as you are not a member."
},
{
"id": "api.command_mute.success_mute",
"translation": "You will not receive notifications for {{.Channel}} until channel mute is turned off."