Low severityNVD Advisory· Published Apr 24, 2025· Updated Apr 24, 2025
Unauthorized Playbooks Post Deletion in Mattermost Playbooks Plugin
CVE-2025-41423
Description
Mattermost versions 10.4.x <= 10.4.2, 10.5.x <= 10.5.0, 9.11.x <= 9.11.10 fail to properly validate permissions for the API endpoint /plugins/playbooks/api/v0/signal/keywords/ignore-thread, allowing any user or attacker to delete posts containing actions created by the Playbooks bot, even without channel access or appropriate permissions.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
github.com/mattermost/mattermost-plugin-playbooksGo | >= 2.0.0 | — |
github.com/mattermost/mattermost-plugin-playbooksGo | < 1.41.0 | 1.41.0 |
github.com/mattermost/mattermost/server/v8Go | < 8.0.0-20250218121836-2b5275d87136 | 8.0.0-20250218121836-2b5275d87136 |
github.com/mattermost/mattermost/server/v8Go | >= 10.4.0 | — |
github.com/mattermost/mattermost/server/v8Go | >= 10.5.0 | — |
github.com/mattermost/mattermost/server/v8Go | >= 9.11.0 | — |
Affected products
1- Range: 10.4.0
Patches
22b5275d87136chore: Update Playbooks plugin to v2.1.1 (#29996)
1 file changed · +1 −1
server/Makefile+1 −1 modified@@ -141,7 +141,7 @@ PLUGIN_PACKAGES += mattermost-plugin-gitlab-v1.9.1 PLUGIN_PACKAGES += mattermost-plugin-jira-v4.2.0 # We need to prepackage both versions of playbooks and install the correct one based on the server license. See MM-60025. PLUGIN_PACKAGES += mattermost-plugin-playbooks-v1.40.0 -PLUGIN_PACKAGES += mattermost-plugin-playbooks-v2.0.1 +PLUGIN_PACKAGES += mattermost-plugin-playbooks-v2.1.1 PLUGIN_PACKAGES += mattermost-plugin-nps-v1.3.3 PLUGIN_PACKAGES += mattermost-plugin-servicenow-v2.3.4 PLUGIN_PACKAGES += mattermost-plugin-zoom-v1.8.0
f9f7064e4d9fFix channel actions modal (#1961)
3 files changed · +21 −21
e2e-tests/tests/integration/playbooks/channels/general_actions_spec.js+0 −17 modified@@ -386,23 +386,6 @@ describe('channels > general actions', {testIsolation: true}, () => { }); }); - it('action settings are disabled for non-channel admin', () => { - // # Login as non-channel admin - cy.apiLogin(testUser); - - // # Go to the test channel - cy.visit(`/${testTeam.name}/channels/${testChannel.name}`); - - // # Open Channel Header and the Channel Actions modal - cy.get('#channelHeaderTitle').click(); - cy.findByText('Channel Actions').click(); - - // * Verify the toggles are disabled - cy.findByRole('dialog', {name: /channel actions/i}).within(() => { - cy.get('input').should('be.disabled'); - }); - }); - it('action settings are reset to the default when switching to a channel with no actions configured', () => { // # Create an additional channel const name = 'New channel ' + Date.now();
server/api/actions.go+6 −0 modified@@ -273,6 +273,12 @@ func (a *ActionsHandler) updateChannelAction(c *Context, w http.ResponseWriter, return } + // Ensure that the action ID in both the URL and the body of the request are the same as well + if newChannelAction.ID != vars["action_id"] { + a.HandleErrorWithCode(w, c.logger, http.StatusBadRequest, "action ID in request body must match action ID in URL", nil) + return + } + // Validate the new action type and payload if err := a.ValidateChannelAction(c, w, &newChannelAction, userID); err != nil { a.HandleErrorWithCode(w, c.logger, http.StatusBadRequest, "invalid action", err)
webapp/src/components/channel_actions_modal.tsx+15 −4 modified@@ -7,9 +7,17 @@ import {useIntl} from 'react-intl'; import {getCurrentChannelId} from 'mattermost-webapp/packages/mattermost-redux/src/selectors/entities/common'; +import Permissions from 'mattermost-redux/constants/permissions'; + +import {getCurrentTeamId} from 'mattermost-webapp/packages/mattermost-redux/src/selectors/entities/teams'; + +import {getChannel} from 'mattermost-webapp/packages/mattermost-redux/src/selectors/entities/channels'; + +import {GlobalState} from 'mattermost-webapp/packages/types/src/store'; + import {fetchChannelActions, saveChannelAction} from 'src/client'; import {hideChannelActionsModal} from 'src/actions'; -import {isChannelActionsModalVisible, isCurrentUserAdmin, isCurrentUserChannelAdmin} from 'src/selectors'; +import {isChannelActionsModalVisible} from 'src/selectors'; import Action from 'src/components/actions_modal_action'; import Trigger, {TriggerKeywords} from 'src/components/actions_modal_trigger'; import { @@ -23,6 +31,7 @@ import { import ActionsModal, {ActionsContainer, TriggersContainer} from 'src/components/actions_modal'; import {CategorizeChannelChildren, RunPlaybookChildren, WelcomeActionChildren} from 'src/components/actions_modal_action_children'; +import {useHasChannelPermission} from 'src/hooks/permissions'; interface ActionState<T extends PayloadType> { id: string | undefined, @@ -70,14 +79,16 @@ const ChannelActionsModal = () => { const dispatch = useDispatch(); const show = useSelector(isChannelActionsModalVisible); const channelID = useSelector(getCurrentChannelId); - const isChannelAdmin = useSelector(isCurrentUserChannelAdmin); - const isSysAdmin = useSelector(isCurrentUserAdmin); + const channel = useSelector((state: GlobalState) => getChannel(state, channelID)); + const teamID = useSelector(getCurrentTeamId); + const publicChannelPermission = useHasChannelPermission(teamID, channelID, Permissions.MANAGE_PUBLIC_CHANNEL_PROPERTIES); + const privateChannelPermission = useHasChannelPermission(teamID, channelID, Permissions.MANAGE_PRIVATE_CHANNEL_PROPERTIES); const [welcomeMsg, setWelcomeMsg, welcomeMsgInit, welcomeMsgReset, welcomeMsgOverwrite] = useActionState(welcomeMsgEmptyState); const [categorization, setCategorization, categorizationInit, categorizationReset, categorizationOverwrite] = useActionState(categorizationEmptyState); const [prompt, setPrompt, promptInit, promptReset, promptOverwrite] = useActionState(promptEmptyState); - const editable = isChannelAdmin || isSysAdmin; + const editable = channel?.type === 'O' ? publicChannelPermission : privateChannelPermission; useEffect(() => { const getActions = async (id: string) => {
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
5- github.com/advisories/GHSA-fr22-5377-f3p7ghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2025-41423ghsaADVISORY
- github.com/mattermost/mattermost-plugin-playbooks/commit/f9f7064e4d9f3918d66bac1f5f9eb28f0723464bghsaWEB
- github.com/mattermost/mattermost/commit/2b5275d87136f07e016c8eca09a2f004b31afc8aghsaWEB
- mattermost.com/security-updatesghsaWEB
News mentions
0No linked articles in our index yet.