VYPR
Moderate severityNVD Advisory· Published Nov 27, 2025· Updated Nov 28, 2025

Information Disclosure in Common Teams API

CVE-2025-12559

Description

Mattermost versions 11.0.x <= 11.0.2, 10.12.x <= 10.12.1, 10.11.x <= 10.11.4, 10.5.x <= 10.5.12 fail to sanitize team email addresses to be visible only to Team Admins, which allows any authenticated user to view team email addresses via the GET /api/v4/channels/{channel_id}/common_teams endpoint

Affected packages

Versions sourced from the GitHub Security Advisory.

PackageAffected versionsPatched versions
github.com/mattermost/mattermost/server/v8Go
< 8.0.0-20251015091448-abbf01b9db458.0.0-20251015091448-abbf01b9db45
github.com/mattermost/mattermost-serverGo
>= 11.0.0, < 11.0.311.0.3
github.com/mattermost/mattermost-serverGo
>= 10.12.0, < 10.12.210.12.2
github.com/mattermost/mattermost-serverGo
>= 10.11.0, < 10.11.510.11.5
github.com/mattermost/mattermost-serverGo
>= 10.5.0, < 10.5.1310.5.13

Affected products

1

Patches

5
7ccb62db7958

[MM-65684] Sanitize teams for /api/v4/channels/{channel_id}/common_teams endpoint (#34110) (#34180)

https://github.com/mattermost/mattermostIbrahim Serdar AcikgozOct 17, 2025via ghsa
2 files changed · +47 55
  • server/channels/api4/channel.go+1 1 modified
    @@ -2427,7 +2427,7 @@ func getGroupMessageMembersCommonTeams(c *Context, w http.ResponseWriter, r *htt
     		return
     	}
     
    -	if err := json.NewEncoder(w).Encode(teams); err != nil {
    +	if err := json.NewEncoder(w).Encode(c.App.SanitizeTeams(*c.AppContext.Session(), teams)); err != nil {
     		c.Logger.Warn("Error while writing response from getGroupMessageMembersCommonTeams", mlog.Err(err))
     	}
     }
    
  • server/channels/app/channel_test.go+46 54 modified
    @@ -2863,69 +2863,61 @@ func TestIsCRTEnabledForUser(t *testing.T) {
     
     func TestGetGroupMessageMembersCommonTeams(t *testing.T) {
     	mainHelper.Parallel(t)
    -	th := SetupWithStoreMock(t)
    +	th := Setup(t).InitBasic()
     	defer th.TearDown()
     
    -	mockStore := th.App.Srv().Store().(*mocks.Store)
    -
    -	mockChannelStore := mocks.ChannelStore{}
    -	mockStore.On("Channel").Return(&mockChannelStore)
    -	mockChannelStore.On("Get", "gm_channel_id", true).Return(&model.Channel{Type: model.ChannelTypeGroup}, nil)
    -
    -	mockTeamStore := mocks.TeamStore{}
    -	mockStore.On("Team").Return(&mockTeamStore)
    -
    -	th.App.Srv().Store().Team()
    -
    -	mockTeamStore.On("GetCommonTeamIDsForMultipleUsers", []string{"user_id_1", "user_id_2"}).Return([]string{"team_id_1", "team_id_2", "team_id_3"}, nil).Times(1)
    -	mockTeamStore.On("GetMany", []string{"team_id_1", "team_id_2", "team_id_3"}).Return(
    -		[]*model.Team{
    -			{DisplayName: "Team 1"},
    -			{DisplayName: "Team 2"},
    -			{DisplayName: "Team 3"},
    -		},
    -		nil,
    -	)
    +	teamsToCreate := 2
    +	usersToCreate := 4 // at least 3 users to create a GM channel, last user is not in any team
    +	teams := make([]string, 0, teamsToCreate)
    +	for i := 0; i < cap(teams); i++ {
    +		team := th.CreateTeam()
    +		defer func(team *model.Team) {
    +			appErr := th.App.PermanentDeleteTeam(th.Context, team)
    +			require.Nil(t, appErr)
    +		}(team)
    +		teams = append(teams, team.Id)
    +	}
     
    -	mockUserStore := mocks.UserStore{}
    -	mockStore.On("User").Return(&mockUserStore)
    -	options := &model.UserGetOptions{
    -		PerPage:     model.ChannelGroupMaxUsers,
    -		Page:        0,
    -		InChannelId: "gm_channel_id",
    -		Inactive:    false,
    -		Active:      true,
    +	users := make([]string, 0, usersToCreate)
    +	for i := 0; i < cap(users); i++ {
    +		user := th.CreateUser()
    +		defer func(user *model.User) {
    +			appErr := th.App.PermanentDeleteUser(th.Context, user)
    +			require.Nil(t, appErr)
    +		}(user)
    +		users = append(users, user.Id)
     	}
    -	mockUserStore.On("GetProfilesInChannel", options).Return([]*model.User{
    -		{
    -			Id: "user_id_1",
    -		},
    -		{
    -			Id: "user_id_2",
    -		},
    -	}, nil)
     
    -	var err error
    -	th.App.ch.srv.teamService, err = teams.New(teams.ServiceConfig{
    -		TeamStore:    &mockTeamStore,
    -		ChannelStore: &mockChannelStore,
    -		GroupStore:   &mocks.GroupStore{},
    -		Users:        th.App.ch.srv.userService,
    -		WebHub:       th.App.ch.srv.platform,
    -		ConfigFn:     th.App.ch.srv.platform.Config,
    -		LicenseFn:    th.App.ch.srv.License,
    -	})
    -	require.NoError(t, err)
    +	for _, teamId := range teams {
    +		// add first 3 users to each team, last user is not in any team
    +		for i := range 3 {
    +			_, _, appErr := th.App.AddUserToTeam(th.Context, teamId, users[i], "")
    +			require.Nil(t, appErr)
    +		}
    +	}
     
    -	commonTeams, appErr := th.App.GetGroupMessageMembersCommonTeams(th.Context, "gm_channel_id")
    +	// create GM channel with first 3 users who share common teams
    +	gmChannel, appErr := th.App.createGroupChannel(th.Context, users[:3], users[0])
     	require.Nil(t, appErr)
    -	require.Equal(t, 3, len(commonTeams))
    +	require.NotNil(t, gmChannel)
     
    -	// case of no common teams
    -	mockTeamStore.On("GetCommonTeamIDsForMultipleUsers", []string{"user_id_1", "user_id_2"}).Return([]string{}, nil)
    -	commonTeams, appErr = th.App.GetGroupMessageMembersCommonTeams(th.Context, "gm_channel_id")
    +	// normally you can't create a GM channel with users that don't share any teams, but we do it here to test the edge case
    +	// create GM channel with last 3 users, where last member is not in any team
    +	otherGMChannel, appErr := th.App.createGroupChannel(th.Context, users[1:], users[0])
     	require.Nil(t, appErr)
    -	require.Equal(t, 0, len(commonTeams))
    +	require.NotNil(t, otherGMChannel)
    +
    +	t.Run("Get teams for GM channel", func(t *testing.T) {
    +		commonTeams, appErr := th.App.GetGroupMessageMembersCommonTeams(th.Context, gmChannel.Id)
    +		require.Nil(t, appErr)
    +		require.Equal(t, 2, len(commonTeams))
    +	})
    +
    +	t.Run("No common teams", func(t *testing.T) {
    +		commonTeams, appErr := th.App.GetGroupMessageMembersCommonTeams(th.Context, otherGMChannel.Id)
    +		require.Nil(t, appErr)
    +		require.Equal(t, 0, len(commonTeams))
    +	})
     }
     
     func TestConvertGroupMessageToChannel(t *testing.T) {
    
5d8719042c18

[MM-65684] Sanitize teams for /api/v4/channels/{channel_id}/common_teams endpoint (#34110) (#34181)

https://github.com/mattermost/mattermostIbrahim Serdar AcikgozOct 17, 2025via ghsa
2 files changed · +47 55
  • server/channels/api4/channel.go+1 1 modified
    @@ -2461,7 +2461,7 @@ func getGroupMessageMembersCommonTeams(c *Context, w http.ResponseWriter, r *htt
     		return
     	}
     
    -	if err := json.NewEncoder(w).Encode(teams); err != nil {
    +	if err := json.NewEncoder(w).Encode(c.App.SanitizeTeams(*c.AppContext.Session(), teams)); err != nil {
     		c.Logger.Warn("Error while writing response from getGroupMessageMembersCommonTeams", mlog.Err(err))
     	}
     }
    
  • server/channels/app/channel_test.go+46 54 modified
    @@ -2863,69 +2863,61 @@ func TestIsCRTEnabledForUser(t *testing.T) {
     
     func TestGetGroupMessageMembersCommonTeams(t *testing.T) {
     	mainHelper.Parallel(t)
    -	th := SetupWithStoreMock(t)
    +	th := Setup(t).InitBasic()
     	defer th.TearDown()
     
    -	mockStore := th.App.Srv().Store().(*mocks.Store)
    -
    -	mockChannelStore := mocks.ChannelStore{}
    -	mockStore.On("Channel").Return(&mockChannelStore)
    -	mockChannelStore.On("Get", "gm_channel_id", true).Return(&model.Channel{Type: model.ChannelTypeGroup}, nil)
    -
    -	mockTeamStore := mocks.TeamStore{}
    -	mockStore.On("Team").Return(&mockTeamStore)
    -
    -	th.App.Srv().Store().Team()
    -
    -	mockTeamStore.On("GetCommonTeamIDsForMultipleUsers", []string{"user_id_1", "user_id_2"}).Return([]string{"team_id_1", "team_id_2", "team_id_3"}, nil).Times(1)
    -	mockTeamStore.On("GetMany", []string{"team_id_1", "team_id_2", "team_id_3"}).Return(
    -		[]*model.Team{
    -			{DisplayName: "Team 1"},
    -			{DisplayName: "Team 2"},
    -			{DisplayName: "Team 3"},
    -		},
    -		nil,
    -	)
    +	teamsToCreate := 2
    +	usersToCreate := 4 // at least 3 users to create a GM channel, last user is not in any team
    +	teams := make([]string, 0, teamsToCreate)
    +	for i := 0; i < cap(teams); i++ {
    +		team := th.CreateTeam()
    +		defer func(team *model.Team) {
    +			appErr := th.App.PermanentDeleteTeam(th.Context, team)
    +			require.Nil(t, appErr)
    +		}(team)
    +		teams = append(teams, team.Id)
    +	}
     
    -	mockUserStore := mocks.UserStore{}
    -	mockStore.On("User").Return(&mockUserStore)
    -	options := &model.UserGetOptions{
    -		PerPage:     model.ChannelGroupMaxUsers,
    -		Page:        0,
    -		InChannelId: "gm_channel_id",
    -		Inactive:    false,
    -		Active:      true,
    +	users := make([]string, 0, usersToCreate)
    +	for i := 0; i < cap(users); i++ {
    +		user := th.CreateUser()
    +		defer func(user *model.User) {
    +			appErr := th.App.PermanentDeleteUser(th.Context, user)
    +			require.Nil(t, appErr)
    +		}(user)
    +		users = append(users, user.Id)
     	}
    -	mockUserStore.On("GetProfilesInChannel", options).Return([]*model.User{
    -		{
    -			Id: "user_id_1",
    -		},
    -		{
    -			Id: "user_id_2",
    -		},
    -	}, nil)
     
    -	var err error
    -	th.App.ch.srv.teamService, err = teams.New(teams.ServiceConfig{
    -		TeamStore:    &mockTeamStore,
    -		ChannelStore: &mockChannelStore,
    -		GroupStore:   &mocks.GroupStore{},
    -		Users:        th.App.ch.srv.userService,
    -		WebHub:       th.App.ch.srv.platform,
    -		ConfigFn:     th.App.ch.srv.platform.Config,
    -		LicenseFn:    th.App.ch.srv.License,
    -	})
    -	require.NoError(t, err)
    +	for _, teamId := range teams {
    +		// add first 3 users to each team, last user is not in any team
    +		for i := range 3 {
    +			_, _, appErr := th.App.AddUserToTeam(th.Context, teamId, users[i], "")
    +			require.Nil(t, appErr)
    +		}
    +	}
     
    -	commonTeams, appErr := th.App.GetGroupMessageMembersCommonTeams(th.Context, "gm_channel_id")
    +	// create GM channel with first 3 users who share common teams
    +	gmChannel, appErr := th.App.createGroupChannel(th.Context, users[:3], users[0])
     	require.Nil(t, appErr)
    -	require.Equal(t, 3, len(commonTeams))
    +	require.NotNil(t, gmChannel)
     
    -	// case of no common teams
    -	mockTeamStore.On("GetCommonTeamIDsForMultipleUsers", []string{"user_id_1", "user_id_2"}).Return([]string{}, nil)
    -	commonTeams, appErr = th.App.GetGroupMessageMembersCommonTeams(th.Context, "gm_channel_id")
    +	// normally you can't create a GM channel with users that don't share any teams, but we do it here to test the edge case
    +	// create GM channel with last 3 users, where last member is not in any team
    +	otherGMChannel, appErr := th.App.createGroupChannel(th.Context, users[1:], users[0])
     	require.Nil(t, appErr)
    -	require.Equal(t, 0, len(commonTeams))
    +	require.NotNil(t, otherGMChannel)
    +
    +	t.Run("Get teams for GM channel", func(t *testing.T) {
    +		commonTeams, appErr := th.App.GetGroupMessageMembersCommonTeams(th.Context, gmChannel.Id)
    +		require.Nil(t, appErr)
    +		require.Equal(t, 2, len(commonTeams))
    +	})
    +
    +	t.Run("No common teams", func(t *testing.T) {
    +		commonTeams, appErr := th.App.GetGroupMessageMembersCommonTeams(th.Context, otherGMChannel.Id)
    +		require.Nil(t, appErr)
    +		require.Equal(t, 0, len(commonTeams))
    +	})
     }
     
     func TestConvertGroupMessageToChannel(t *testing.T) {
    
9f54e5cdc3ae

[MM-65684] Sanitize teams for /api/v4/channels/{channel_id}/common_teams endpoint (#34110) (#34182)

https://github.com/mattermost/mattermostIbrahim Serdar AcikgozOct 17, 2025via ghsa
2 files changed · +47 55
  • server/channels/api4/channel.go+1 1 modified
    @@ -2467,7 +2467,7 @@ func getGroupMessageMembersCommonTeams(c *Context, w http.ResponseWriter, r *htt
     		return
     	}
     
    -	if err := json.NewEncoder(w).Encode(teams); err != nil {
    +	if err := json.NewEncoder(w).Encode(c.App.SanitizeTeams(*c.AppContext.Session(), teams)); err != nil {
     		c.Logger.Warn("Error while writing response from getGroupMessageMembersCommonTeams", mlog.Err(err))
     	}
     }
    
  • server/channels/app/channel_test.go+46 54 modified
    @@ -2863,69 +2863,61 @@ func TestIsCRTEnabledForUser(t *testing.T) {
     
     func TestGetGroupMessageMembersCommonTeams(t *testing.T) {
     	mainHelper.Parallel(t)
    -	th := SetupWithStoreMock(t)
    +	th := Setup(t).InitBasic()
     	defer th.TearDown()
     
    -	mockStore := th.App.Srv().Store().(*mocks.Store)
    -
    -	mockChannelStore := mocks.ChannelStore{}
    -	mockStore.On("Channel").Return(&mockChannelStore)
    -	mockChannelStore.On("Get", "gm_channel_id", true).Return(&model.Channel{Type: model.ChannelTypeGroup}, nil)
    -
    -	mockTeamStore := mocks.TeamStore{}
    -	mockStore.On("Team").Return(&mockTeamStore)
    -
    -	th.App.Srv().Store().Team()
    -
    -	mockTeamStore.On("GetCommonTeamIDsForMultipleUsers", []string{"user_id_1", "user_id_2"}).Return([]string{"team_id_1", "team_id_2", "team_id_3"}, nil).Times(1)
    -	mockTeamStore.On("GetMany", []string{"team_id_1", "team_id_2", "team_id_3"}).Return(
    -		[]*model.Team{
    -			{DisplayName: "Team 1"},
    -			{DisplayName: "Team 2"},
    -			{DisplayName: "Team 3"},
    -		},
    -		nil,
    -	)
    +	teamsToCreate := 2
    +	usersToCreate := 4 // at least 3 users to create a GM channel, last user is not in any team
    +	teams := make([]string, 0, teamsToCreate)
    +	for i := 0; i < cap(teams); i++ {
    +		team := th.CreateTeam()
    +		defer func(team *model.Team) {
    +			appErr := th.App.PermanentDeleteTeam(th.Context, team)
    +			require.Nil(t, appErr)
    +		}(team)
    +		teams = append(teams, team.Id)
    +	}
     
    -	mockUserStore := mocks.UserStore{}
    -	mockStore.On("User").Return(&mockUserStore)
    -	options := &model.UserGetOptions{
    -		PerPage:     model.ChannelGroupMaxUsers,
    -		Page:        0,
    -		InChannelId: "gm_channel_id",
    -		Inactive:    false,
    -		Active:      true,
    +	users := make([]string, 0, usersToCreate)
    +	for i := 0; i < cap(users); i++ {
    +		user := th.CreateUser()
    +		defer func(user *model.User) {
    +			appErr := th.App.PermanentDeleteUser(th.Context, user)
    +			require.Nil(t, appErr)
    +		}(user)
    +		users = append(users, user.Id)
     	}
    -	mockUserStore.On("GetProfilesInChannel", options).Return([]*model.User{
    -		{
    -			Id: "user_id_1",
    -		},
    -		{
    -			Id: "user_id_2",
    -		},
    -	}, nil)
     
    -	var err error
    -	th.App.ch.srv.teamService, err = teams.New(teams.ServiceConfig{
    -		TeamStore:    &mockTeamStore,
    -		ChannelStore: &mockChannelStore,
    -		GroupStore:   &mocks.GroupStore{},
    -		Users:        th.App.ch.srv.userService,
    -		WebHub:       th.App.ch.srv.platform,
    -		ConfigFn:     th.App.ch.srv.platform.Config,
    -		LicenseFn:    th.App.ch.srv.License,
    -	})
    -	require.NoError(t, err)
    +	for _, teamId := range teams {
    +		// add first 3 users to each team, last user is not in any team
    +		for i := range 3 {
    +			_, _, appErr := th.App.AddUserToTeam(th.Context, teamId, users[i], "")
    +			require.Nil(t, appErr)
    +		}
    +	}
     
    -	commonTeams, appErr := th.App.GetGroupMessageMembersCommonTeams(th.Context, "gm_channel_id")
    +	// create GM channel with first 3 users who share common teams
    +	gmChannel, appErr := th.App.createGroupChannel(th.Context, users[:3], users[0])
     	require.Nil(t, appErr)
    -	require.Equal(t, 3, len(commonTeams))
    +	require.NotNil(t, gmChannel)
     
    -	// case of no common teams
    -	mockTeamStore.On("GetCommonTeamIDsForMultipleUsers", []string{"user_id_1", "user_id_2"}).Return([]string{}, nil)
    -	commonTeams, appErr = th.App.GetGroupMessageMembersCommonTeams(th.Context, "gm_channel_id")
    +	// normally you can't create a GM channel with users that don't share any teams, but we do it here to test the edge case
    +	// create GM channel with last 3 users, where last member is not in any team
    +	otherGMChannel, appErr := th.App.createGroupChannel(th.Context, users[1:], users[0])
     	require.Nil(t, appErr)
    -	require.Equal(t, 0, len(commonTeams))
    +	require.NotNil(t, otherGMChannel)
    +
    +	t.Run("Get teams for GM channel", func(t *testing.T) {
    +		commonTeams, appErr := th.App.GetGroupMessageMembersCommonTeams(th.Context, gmChannel.Id)
    +		require.Nil(t, appErr)
    +		require.Equal(t, 2, len(commonTeams))
    +	})
    +
    +	t.Run("No common teams", func(t *testing.T) {
    +		commonTeams, appErr := th.App.GetGroupMessageMembersCommonTeams(th.Context, otherGMChannel.Id)
    +		require.Nil(t, appErr)
    +		require.Equal(t, 0, len(commonTeams))
    +	})
     }
     
     func TestConvertGroupMessageToChannel(t *testing.T) {
    
649aee8fa918

[MM-65684] Sanitize teams for /api/v4/channels/{channel_id}/common_teams endpoint (#34110) (#34183)

https://github.com/mattermost/mattermostIbrahim Serdar AcikgozOct 17, 2025via ghsa
2 files changed · +47 55
  • server/channels/api4/channel.go+1 1 modified
    @@ -2432,7 +2432,7 @@ func getGroupMessageMembersCommonTeams(c *Context, w http.ResponseWriter, r *htt
     		return
     	}
     
    -	if err := json.NewEncoder(w).Encode(teams); err != nil {
    +	if err := json.NewEncoder(w).Encode(c.App.SanitizeTeams(*c.AppContext.Session(), teams)); err != nil {
     		c.Logger.Warn("Error while writing response from getGroupMessageMembersCommonTeams", mlog.Err(err))
     	}
     }
    
  • server/channels/app/channel_test.go+46 54 modified
    @@ -2743,69 +2743,61 @@ func TestIsCRTEnabledForUser(t *testing.T) {
     }
     
     func TestGetGroupMessageMembersCommonTeams(t *testing.T) {
    -	th := SetupWithStoreMock(t)
    +	th := Setup(t).InitBasic()
     	defer th.TearDown()
     
    -	mockStore := th.App.Srv().Store().(*mocks.Store)
    -
    -	mockChannelStore := mocks.ChannelStore{}
    -	mockStore.On("Channel").Return(&mockChannelStore)
    -	mockChannelStore.On("Get", "gm_channel_id", true).Return(&model.Channel{Type: model.ChannelTypeGroup}, nil)
    -
    -	mockTeamStore := mocks.TeamStore{}
    -	mockStore.On("Team").Return(&mockTeamStore)
    -
    -	th.App.Srv().Store().Team()
    -
    -	mockTeamStore.On("GetCommonTeamIDsForMultipleUsers", []string{"user_id_1", "user_id_2"}).Return([]string{"team_id_1", "team_id_2", "team_id_3"}, nil).Times(1)
    -	mockTeamStore.On("GetMany", []string{"team_id_1", "team_id_2", "team_id_3"}).Return(
    -		[]*model.Team{
    -			{DisplayName: "Team 1"},
    -			{DisplayName: "Team 2"},
    -			{DisplayName: "Team 3"},
    -		},
    -		nil,
    -	)
    +	teamsToCreate := 2
    +	usersToCreate := 4 // at least 3 users to create a GM channel, last user is not in any team
    +	teams := make([]string, 0, teamsToCreate)
    +	for i := 0; i < cap(teams); i++ {
    +		team := th.CreateTeam()
    +		defer func(team *model.Team) {
    +			appErr := th.App.PermanentDeleteTeam(th.Context, team)
    +			require.Nil(t, appErr)
    +		}(team)
    +		teams = append(teams, team.Id)
    +	}
     
    -	mockUserStore := mocks.UserStore{}
    -	mockStore.On("User").Return(&mockUserStore)
    -	options := &model.UserGetOptions{
    -		PerPage:     model.ChannelGroupMaxUsers,
    -		Page:        0,
    -		InChannelId: "gm_channel_id",
    -		Inactive:    false,
    -		Active:      true,
    +	users := make([]string, 0, usersToCreate)
    +	for i := 0; i < cap(users); i++ {
    +		user := th.CreateUser()
    +		defer func(user *model.User) {
    +			appErr := th.App.PermanentDeleteUser(th.Context, user)
    +			require.Nil(t, appErr)
    +		}(user)
    +		users = append(users, user.Id)
     	}
    -	mockUserStore.On("GetProfilesInChannel", options).Return([]*model.User{
    -		{
    -			Id: "user_id_1",
    -		},
    -		{
    -			Id: "user_id_2",
    -		},
    -	}, nil)
     
    -	var err error
    -	th.App.ch.srv.teamService, err = teams.New(teams.ServiceConfig{
    -		TeamStore:    &mockTeamStore,
    -		ChannelStore: &mockChannelStore,
    -		GroupStore:   &mocks.GroupStore{},
    -		Users:        th.App.ch.srv.userService,
    -		WebHub:       th.App.ch.srv.platform,
    -		ConfigFn:     th.App.ch.srv.platform.Config,
    -		LicenseFn:    th.App.ch.srv.License,
    -	})
    -	require.NoError(t, err)
    +	for _, teamId := range teams {
    +		// add first 3 users to each team, last user is not in any team
    +		for i := range 3 {
    +			_, _, appErr := th.App.AddUserToTeam(th.Context, teamId, users[i], "")
    +			require.Nil(t, appErr)
    +		}
    +	}
     
    -	commonTeams, appErr := th.App.GetGroupMessageMembersCommonTeams(th.Context, "gm_channel_id")
    +	// create GM channel with first 3 users who share common teams
    +	gmChannel, appErr := th.App.createGroupChannel(th.Context, users[:3])
     	require.Nil(t, appErr)
    -	require.Equal(t, 3, len(commonTeams))
    +	require.NotNil(t, gmChannel)
     
    -	// case of no common teams
    -	mockTeamStore.On("GetCommonTeamIDsForMultipleUsers", []string{"user_id_1", "user_id_2"}).Return([]string{}, nil)
    -	commonTeams, appErr = th.App.GetGroupMessageMembersCommonTeams(th.Context, "gm_channel_id")
    +	// normally you can't create a GM channel with users that don't share any teams, but we do it here to test the edge case
    +	// create GM channel with last 3 users, where last member is not in any team
    +	otherGMChannel, appErr := th.App.createGroupChannel(th.Context, users[1:])
     	require.Nil(t, appErr)
    -	require.Equal(t, 0, len(commonTeams))
    +	require.NotNil(t, otherGMChannel)
    +
    +	t.Run("Get teams for GM channel", func(t *testing.T) {
    +		commonTeams, appErr := th.App.GetGroupMessageMembersCommonTeams(th.Context, gmChannel.Id)
    +		require.Nil(t, appErr)
    +		require.Equal(t, 2, len(commonTeams))
    +	})
    +
    +	t.Run("No common teams", func(t *testing.T) {
    +		commonTeams, appErr := th.App.GetGroupMessageMembersCommonTeams(th.Context, otherGMChannel.Id)
    +		require.Nil(t, appErr)
    +		require.Equal(t, 0, len(commonTeams))
    +	})
     }
     
     func TestConvertGroupMessageToChannel(t *testing.T) {
    
abbf01b9db45

[MM-65684] Sanitize teams for /api/v4/channels/{channel_id}/common_teams endpoint (#34110)

https://github.com/mattermost/mattermostIbrahim Serdar AcikgozOct 15, 2025via ghsa
2 files changed · +47 55
  • server/channels/api4/channel.go+1 1 modified
    @@ -2462,7 +2462,7 @@ func getDirectOrGroupMessageMembersCommonTeams(c *Context, w http.ResponseWriter
     		return
     	}
     
    -	if err := json.NewEncoder(w).Encode(teams); err != nil {
    +	if err := json.NewEncoder(w).Encode(c.App.SanitizeTeams(*c.AppContext.Session(), teams)); err != nil {
     		c.Logger.Warn("Error while writing response from getDirectOrGroupMessageMembersCommonTeams", mlog.Err(err))
     	}
     }
    
  • server/channels/app/channel_test.go+46 54 modified
    @@ -2862,69 +2862,61 @@ func TestIsCRTEnabledForUser(t *testing.T) {
     
     func TestGetDirectOrGroupMessageMembersCommonTeams(t *testing.T) {
     	mainHelper.Parallel(t)
    -	th := SetupWithStoreMock(t)
    +	th := Setup(t).InitBasic()
     	defer th.TearDown()
     
    -	mockStore := th.App.Srv().Store().(*mocks.Store)
    -
    -	mockChannelStore := mocks.ChannelStore{}
    -	mockStore.On("Channel").Return(&mockChannelStore)
    -	mockChannelStore.On("Get", "gm_channel_id", true).Return(&model.Channel{Type: model.ChannelTypeGroup}, nil)
    -
    -	mockTeamStore := mocks.TeamStore{}
    -	mockStore.On("Team").Return(&mockTeamStore)
    -
    -	th.App.Srv().Store().Team()
    -
    -	mockTeamStore.On("GetCommonTeamIDsForMultipleUsers", []string{"user_id_1", "user_id_2"}).Return([]string{"team_id_1", "team_id_2", "team_id_3"}, nil).Times(1)
    -	mockTeamStore.On("GetMany", []string{"team_id_1", "team_id_2", "team_id_3"}).Return(
    -		[]*model.Team{
    -			{DisplayName: "Team 1"},
    -			{DisplayName: "Team 2"},
    -			{DisplayName: "Team 3"},
    -		},
    -		nil,
    -	)
    +	teamsToCreate := 2
    +	usersToCreate := 4 // at least 3 users to create a GM channel, last user is not in any team
    +	teams := make([]string, 0, teamsToCreate)
    +	for i := 0; i < cap(teams); i++ {
    +		team := th.CreateTeam()
    +		defer func(team *model.Team) {
    +			appErr := th.App.PermanentDeleteTeam(th.Context, team)
    +			require.Nil(t, appErr)
    +		}(team)
    +		teams = append(teams, team.Id)
    +	}
     
    -	mockUserStore := mocks.UserStore{}
    -	mockStore.On("User").Return(&mockUserStore)
    -	options := &model.UserGetOptions{
    -		PerPage:     model.ChannelGroupMaxUsers,
    -		Page:        0,
    -		InChannelId: "gm_channel_id",
    -		Inactive:    false,
    -		Active:      true,
    +	users := make([]string, 0, usersToCreate)
    +	for i := 0; i < cap(users); i++ {
    +		user := th.CreateUser()
    +		defer func(user *model.User) {
    +			appErr := th.App.PermanentDeleteUser(th.Context, user)
    +			require.Nil(t, appErr)
    +		}(user)
    +		users = append(users, user.Id)
     	}
    -	mockUserStore.On("GetProfilesInChannel", options).Return([]*model.User{
    -		{
    -			Id: "user_id_1",
    -		},
    -		{
    -			Id: "user_id_2",
    -		},
    -	}, nil)
     
    -	var err error
    -	th.App.ch.srv.teamService, err = teams.New(teams.ServiceConfig{
    -		TeamStore:    &mockTeamStore,
    -		ChannelStore: &mockChannelStore,
    -		GroupStore:   &mocks.GroupStore{},
    -		Users:        th.App.ch.srv.userService,
    -		WebHub:       th.App.ch.srv.platform,
    -		ConfigFn:     th.App.ch.srv.platform.Config,
    -		LicenseFn:    th.App.ch.srv.License,
    -	})
    -	require.NoError(t, err)
    +	for _, teamId := range teams {
    +		// add first 3 users to each team, last user is not in any team
    +		for i := range 3 {
    +			_, _, appErr := th.App.AddUserToTeam(th.Context, teamId, users[i], "")
    +			require.Nil(t, appErr)
    +		}
    +	}
     
    -	commonTeams, appErr := th.App.GetDirectOrGroupMessageMembersCommonTeams(th.Context, "gm_channel_id")
    +	// create GM channel with first 3 users who share common teams
    +	gmChannel, appErr := th.App.createGroupChannel(th.Context, users[:3], users[0])
     	require.Nil(t, appErr)
    -	require.Equal(t, 3, len(commonTeams))
    +	require.NotNil(t, gmChannel)
     
    -	// case of no common teams
    -	mockTeamStore.On("GetCommonTeamIDsForMultipleUsers", []string{"user_id_1", "user_id_2"}).Return([]string{}, nil)
    -	commonTeams, appErr = th.App.GetDirectOrGroupMessageMembersCommonTeams(th.Context, "gm_channel_id")
    +	// normally you can't create a GM channel with users that don't share any teams, but we do it here to test the edge case
    +	// create GM channel with last 3 users, where last member is not in any team
    +	otherGMChannel, appErr := th.App.createGroupChannel(th.Context, users[1:], users[0])
     	require.Nil(t, appErr)
    -	require.Equal(t, 0, len(commonTeams))
    +	require.NotNil(t, otherGMChannel)
    +
    +	t.Run("Get teams for GM channel", func(t *testing.T) {
    +		commonTeams, appErr := th.App.GetDirectOrGroupMessageMembersCommonTeams(th.Context, gmChannel.Id)
    +		require.Nil(t, appErr)
    +		require.Equal(t, 2, len(commonTeams))
    +	})
    +
    +	t.Run("No common teams", func(t *testing.T) {
    +		commonTeams, appErr := th.App.GetDirectOrGroupMessageMembersCommonTeams(th.Context, otherGMChannel.Id)
    +		require.Nil(t, appErr)
    +		require.Equal(t, 0, len(commonTeams))
    +	})
     }
     
     func TestConvertGroupMessageToChannel(t *testing.T) {
    

Vulnerability mechanics

Generated by null/stub on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

9

News mentions

0

No linked articles in our index yet.